nodes: 0, module; 1, function_definition; 2, function_name:_pcca_connected_isa; 3, parameters; 4, block; 5, identifier:evec; 6, identifier:n_clusters; 7, expression_statement; 8, expression_statement; 9, comment:# do we have enough eigenvectors?; 10, if_statement; 11, comment:# check if the first, and only the first eigenvector is constant; 12, expression_statement; 13, assert_statement; 14, assert_statement; 15, comment:# local copy of the eigenvectors; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, comment:# representative states; 20, expression_statement; 21, comment:# select the first representative as the most outlying point; 22, for_statement; 23, comment:# translate coordinates to make the first representative the origin; 24, expression_statement; 25, comment:# select the other m-1 representatives using a Gram-Schmidt orthogonalization; 26, for_statement; 27, comment:# print "Final selection ", ind; 28, comment:# obtain transformation matrix of eigenvectors to membership matrix; 29, expression_statement; 30, comment:#print "Rotation matrix \n ", rot_mat; 31, comment:# compute membership matrix; 32, expression_statement; 33, comment:#print "chi \n ", chi; 34, return_statement; 35, comment:"""
      PCCA+ spectral clustering method using the inner simplex algorithm.
  
      Clusters the first n_cluster eigenvectors of a transition matrix in order to cluster the states.
      This function assumes that the state space is fully connected, i.e. the transition matrix whose
      eigenvectors are used is supposed to have only one eigenvalue 1, and the corresponding first
      eigenvector (evec[:,0]) must be constant.
  
      Parameters
      ----------
      eigenvectors : ndarray
          A matrix with the sorted eigenvectors in the columns. The stationary eigenvector should
          be first, then the one to the slowest relaxation process, etc.
  
      n_clusters : int
          Number of clusters to group to.
  
      Returns
      -------
      (chi, rot_mat)
  
      chi : ndarray (n x m)
          A matrix containing the probability or membership of each state to be assigned to each cluster.
          The rows sum to 1.
  
      rot_mat : ndarray (m x m)
          A rotation matrix that rotates the dominant eigenvectors to yield the PCCA memberships, i.e.:
          chi = np.dot(evec, rot_matrix
  
      References
      ----------
      [1] P. Deuflhard and M. Weber, Robust Perron cluster analysis in conformation dynamics.
          in: Linear Algebra Appl. 398C M. Dellnitz and S. Kirkland and M. Neumann and C. Schuette (Editors)
          Elsevier, New York, 2005, pp. 161-184
  
      """; 36, assignment; 37, comparison_operator:n_clusters > m; 38, block; 39, assignment; 40, comparison_operator:diffs[0] < 1e-6; 41, concatenated_string; 42, comparison_operator:diffs[1] > 1e-6; 43, concatenated_string; 44, assignment; 45, assignment; 46, assignment; 47, assignment; 48, tuple_pattern; 49, call; 50, block; 51, augmented_assignment; 52, identifier:k; 53, call; 54, block; 55, assignment; 56, assignment; 57, tuple; 58, tuple_pattern; 59, attribute; 60, identifier:n_clusters; 61, identifier:m; 62, raise_statement; 63, identifier:diffs; 64, call; 65, subscript; 66, float:1e-6; 67, string:"First eigenvector is not constant. This indicates that the transition matrix "; 68, string:"is not connected or the eigenvectors are incorrectly sorted. Cannot do PCCA."; 69, subscript; 70, float:1e-6; 71, string:"An eigenvector after the first one is constant. "; 72, string:"Probably the eigenvectors are incorrectly sorted. Cannot do PCCA."; 73, identifier:c; 74, subscript; 75, identifier:ortho_sys; 76, call; 77, identifier:max_dist; 78, float:0.0; 79, identifier:ind; 80, call; 81, identifier:i; 82, identifier:row; 83, identifier:enumerate; 84, argument_list; 85, if_statement; 86, identifier:ortho_sys; 87, subscript; 88, identifier:range; 89, argument_list; 90, expression_statement; 91, expression_statement; 92, comment:# select next farthest point that is not yet a representative; 93, for_statement; 94, expression_statement; 95, identifier:rot_mat; 96, call; 97, identifier:chi; 98, call; 99, identifier:chi; 100, identifier:rot_mat; 101, identifier:n; 102, identifier:m; 103, identifier:evec; 104, identifier:shape; 105, call; 106, attribute; 107, argument_list; 108, identifier:diffs; 109, integer:0; 110, identifier:diffs; 111, integer:1; 112, identifier:evec; 113, slice; 114, call; 115, attribute; 116, argument_list; 117, attribute; 118, argument_list; 119, identifier:c; 120, comparison_operator:np.linalg.norm(row, 2) > max_dist; 121, block; 122, identifier:c; 123, subscript; 124, None; 125, integer:1; 126, identifier:n_clusters; 127, assignment; 128, assignment; 129, tuple_pattern; 130, call; 131, block; 132, augmented_assignment; 133, attribute; 134, argument_list; 135, attribute; 136, argument_list; 137, identifier:ValueError; 138, argument_list; 139, identifier:np; 140, identifier:abs; 141, binary_operator:np.max(evec, axis=0) - np.min(evec, axis=0); 142, identifier:list; 143, argument_list; 144, identifier:np; 145, identifier:copy; 146, identifier:c; 147, identifier:np; 148, identifier:zeros; 149, identifier:n_clusters; 150, keyword_argument; 151, call; 152, identifier:max_dist; 153, expression_statement; 154, expression_statement; 155, identifier:ind; 156, integer:0; 157, identifier:max_dist; 158, float:0.0; 159, identifier:temp; 160, call; 161, identifier:i; 162, identifier:row; 163, identifier:enumerate; 164, argument_list; 165, expression_statement; 166, expression_statement; 167, if_statement; 168, identifier:ortho_sys; 169, call; 170, attribute; 171, identifier:inv; 172, subscript; 173, identifier:np; 174, identifier:dot; 175, identifier:c; 176, identifier:rot_mat; 177, binary_operator:"Cannot cluster the (" + str(n) + " x " + str(m)
                           + " eigenvector matrix to " + str(n_clusters) + " clusters."; 178, call; 179, call; 180, call; 181, identifier:dtype; 182, attribute; 183, attribute; 184, argument_list; 185, assignment; 186, assignment; 187, attribute; 188, argument_list; 189, identifier:ortho_sys; 190, augmented_assignment; 191, assignment; 192, boolean_operator; 193, block; 194, attribute; 195, argument_list; 196, identifier:np; 197, identifier:linalg; 198, identifier:c; 199, identifier:ind; 200, binary_operator:"Cannot cluster the (" + str(n) + " x " + str(m)
                           + " eigenvector matrix to " + str(n_clusters); 201, string:" clusters."; 202, attribute; 203, argument_list; 204, attribute; 205, argument_list; 206, identifier:range; 207, argument_list; 208, identifier:np; 209, identifier:int32; 210, attribute; 211, identifier:norm; 212, identifier:row; 213, integer:2; 214, identifier:max_dist; 215, call; 216, subscript; 217, identifier:i; 218, identifier:np; 219, identifier:copy; 220, subscript; 221, identifier:row; 222, call; 223, identifier:distt; 224, call; 225, comparison_operator:distt > max_dist; 226, comparison_operator:i not in ind[0:k]; 227, expression_statement; 228, expression_statement; 229, attribute; 230, identifier:norm; 231, subscript; 232, integer:2; 233, binary_operator:"Cannot cluster the (" + str(n) + " x " + str(m)
                           + " eigenvector matrix to "; 234, call; 235, identifier:np; 236, identifier:max; 237, identifier:evec; 238, keyword_argument; 239, identifier:np; 240, identifier:min; 241, identifier:evec; 242, keyword_argument; 243, identifier:n_clusters; 244, identifier:np; 245, identifier:linalg; 246, attribute; 247, argument_list; 248, identifier:ind; 249, integer:0; 250, identifier:ortho_sys; 251, subscript; 252, attribute; 253, argument_list; 254, attribute; 255, argument_list; 256, identifier:distt; 257, identifier:max_dist; 258, identifier:i; 259, subscript; 260, assignment; 261, assignment; 262, identifier:np; 263, identifier:linalg; 264, identifier:ortho_sys; 265, subscript; 266, binary_operator:"Cannot cluster the (" + str(n) + " x " + str(m); 267, string:" eigenvector matrix to "; 268, identifier:str; 269, argument_list; 270, identifier:axis; 271, integer:0; 272, identifier:axis; 273, integer:0; 274, attribute; 275, identifier:norm; 276, identifier:row; 277, integer:2; 278, identifier:ind; 279, binary_operator:k - 1; 280, identifier:np; 281, identifier:dot; 282, call; 283, identifier:temp; 284, attribute; 285, identifier:norm; 286, identifier:row; 287, integer:2; 288, identifier:ind; 289, slice; 290, identifier:max_dist; 291, identifier:distt; 292, subscript; 293, identifier:i; 294, identifier:ind; 295, identifier:k; 296, binary_operator:"Cannot cluster the (" + str(n) + " x "; 297, call; 298, identifier:n_clusters; 299, identifier:np; 300, identifier:linalg; 301, identifier:k; 302, integer:1; 303, attribute; 304, argument_list; 305, identifier:np; 306, identifier:linalg; 307, integer:0; 308, identifier:k; 309, identifier:ind; 310, identifier:k; 311, binary_operator:"Cannot cluster the (" + str(n); 312, string:" x "; 313, identifier:str; 314, argument_list; 315, identifier:np; 316, identifier:dot; 317, identifier:temp; 318, call; 319, string:"Cannot cluster the ("; 320, call; 321, identifier:m; 322, attribute; 323, argument_list; 324, identifier:str; 325, argument_list; 326, identifier:np; 327, identifier:transpose; 328, identifier:row; 329, identifier:n
code: def _pcca_connected_isa(evec, n_clusters):
      """
      PCCA+ spectral clustering method using the inner simplex algorithm.
  
      Clusters the first n_cluster eigenvectors of a transition matrix in order to cluster the states.
      This function assumes that the state space is fully connected, i.e. the transition matrix whose
      eigenvectors are used is supposed to have only one eigenvalue 1, and the corresponding first
      eigenvector (evec[:,0]) must be constant.
  
      Parameters
      ----------
      eigenvectors : ndarray
          A matrix with the sorted eigenvectors in the columns. The stationary eigenvector should
          be first, then the one to the slowest relaxation process, etc.
  
      n_clusters : int
          Number of clusters to group to.
  
      Returns
      -------
      (chi, rot_mat)
  
      chi : ndarray (n x m)
          A matrix containing the probability or membership of each state to be assigned to each cluster.
          The rows sum to 1.
  
      rot_mat : ndarray (m x m)
          A rotation matrix that rotates the dominant eigenvectors to yield the PCCA memberships, i.e.:
          chi = np.dot(evec, rot_matrix
  
      References
      ----------
      [1] P. Deuflhard and M. Weber, Robust Perron cluster analysis in conformation dynamics.
          in: Linear Algebra Appl. 398C M. Dellnitz and S. Kirkland and M. Neumann and C. Schuette (Editors)
          Elsevier, New York, 2005, pp. 161-184
  
      """
      (n, m) = evec.shape
  
      # do we have enough eigenvectors?
      if n_clusters > m:
          raise ValueError("Cannot cluster the (" + str(n) + " x " + str(m)
                           + " eigenvector matrix to " + str(n_clusters) + " clusters.")
  
      # check if the first, and only the first eigenvector is constant
      diffs = np.abs(np.max(evec, axis=0) - np.min(evec, axis=0))
      assert diffs[0] < 1e-6, "First eigenvector is not constant. This indicates that the transition matrix " \
                              "is not connected or the eigenvectors are incorrectly sorted. Cannot do PCCA."
      assert diffs[1] > 1e-6, "An eigenvector after the first one is constant. " \
                              "Probably the eigenvectors are incorrectly sorted. Cannot do PCCA."
  
      # local copy of the eigenvectors
      c = evec[:, list(range(n_clusters))]
  
      ortho_sys = np.copy(c)
      max_dist = 0.0
  
      # representative states
      ind = np.zeros(n_clusters, dtype=np.int32)
  
      # select the first representative as the most outlying point
      for (i, row) in enumerate(c):
          if np.linalg.norm(row, 2) > max_dist:
              max_dist = np.linalg.norm(row, 2)
              ind[0] = i
  
      # translate coordinates to make the first representative the origin
      ortho_sys -= c[ind[0], None]
  
      # select the other m-1 representatives using a Gram-Schmidt orthogonalization
      for k in range(1, n_clusters):
          max_dist = 0.0
          temp = np.copy(ortho_sys[ind[k - 1]])
  
          # select next farthest point that is not yet a representative
          for (i, row) in enumerate(ortho_sys):
              row -= np.dot(np.dot(temp, np.transpose(row)), temp)
              distt = np.linalg.norm(row, 2)
              if distt > max_dist and i not in ind[0:k]:
                  max_dist = distt
                  ind[k] = i
          ortho_sys /= np.linalg.norm(ortho_sys[ind[k]], 2)
  
      # print "Final selection ", ind
  
      # obtain transformation matrix of eigenvectors to membership matrix
      rot_mat = np.linalg.inv(c[ind])
      #print "Rotation matrix \n ", rot_mat
  
      # compute membership matrix
      chi = np.dot(c, rot_mat)
      #print "chi \n ", chi
  
      return (chi, rot_mat)