def test_pca(): p = np.array([[4., 2., 0.6], [4.2, 2.1, 0.59], [3.9, 2.0, 0.58], [4.3, 2.1, 0.62], [4.1, 2.2, 0.63]]) RES_COV = np.array([[0.025, 0.0075, 0.00175], [0.0075, 0.0070, 0.00135], [0.00175, 0.00135, 0.00043]]) RES_EIGV = np.array([[ 0.93676841, 0.34958469, -0.0159843 ], [ 0.34148069, -0.92313136, -0.1766902 ], [ 0.0765238 , -0.16005947, 0.98413672]]) RES_EIGS = np.array([0.0278769, 0.00439387, 0.0001592]) eigs, eigv = pca(p) nt.assert_true(np.allclose(eigs, RES_EIGS)) nt.assert_true(np.allclose(eigv[:,0], RES_EIGV[:,0]) or np.allclose(eigv[:, 0], -1. * RES_EIGV[:, 0])) nt.assert_true(np.allclose(eigv[:,1], RES_EIGV[:,1]) or np.allclose(eigv[:, 1], -1. * RES_EIGV[:, 1])) nt.assert_true(np.allclose(eigv[:,2], RES_EIGV[:,2]) or np.allclose(eigv[:, 2], -1. * RES_EIGV[:, 2]))
def principal_direction_extent(tree): '''Calculate the extent of a tree, that is the maximum distance between the projections on the principal directions of the covariance matrix of the x,y,z points of the nodes of the tree. Input tree : a tree object Returns extents : the extents for each of the eigenvectors of the cov matrix eigs : eigenvalues of the covariance matrix eigv : respective eigenvectors of the covariance matrix ''' # extract the x,y,z coordinates of all the points in the tree points = np.array([value[COLS.X: COLS.R]for value in val_iter(ipreorder(tree))]) # center the points around 0.0 points -= np.mean(points, axis=0) # principal components _, eigv = pca(points) extent = np.zeros(3) for i in range(eigv.shape[1]): # orthogonal projection onto the direction of the v component scalar_projs = np.sort(np.array([np.dot(p, eigv[:, i]) for p in points])) extent[i] = scalar_projs[-1] if scalar_projs[0] < 0.: extent -= scalar_projs[0] return extent