nodes: 0, module; 1, function_definition; 2, function_name:diagonalize_real_symmetric_and_sorted_diagonal_matrices; 3, parameters; 4, type; 5, block; 6, typed_parameter; 7, typed_parameter; 8, keyword_separator; 9, typed_default_parameter; 10, typed_default_parameter; 11, typed_default_parameter; 12, attribute; 13, expression_statement; 14, comment:# Verify preconditions.; 15, if_statement; 16, function_definition; 17, comment:# Because the symmetric matrix commutes with the diagonal singulars matrix,; 18, comment:# the symmetric matrix should be block-diagonal with a block boundary; 19, comment:# wherever the singular values happen change. So we can use the singular; 20, comment:# values to extract blocks that can be independently diagonalized.; 21, expression_statement; 22, comment:# Build the overall diagonalization by diagonalizing each block.; 23, expression_statement; 24, for_statement; 25, return_statement; 26, identifier:symmetric_matrix; 27, type; 28, identifier:diagonal_matrix; 29, type; 30, identifier:rtol; 31, type; 32, float:1e-5; 33, identifier:atol; 34, type; 35, float:1e-8; 36, identifier:check_preconditions; 37, type; 38, True; 39, identifier:np; 40, identifier:ndarray; 41, comment:"""Returns an orthogonal matrix that diagonalizes both given matrices.
  
      The given matrices must commute.
      Guarantees that the sorted diagonal matrix is not permuted by the
      diagonalization (except for nearly-equal values).
  
      Args:
          symmetric_matrix: A real symmetric matrix.
          diagonal_matrix: A real diagonal matrix with entries along the diagonal
              sorted into descending order.
          rtol: Relative numeric error threshold.
          atol: Absolute numeric error threshold.
          check_preconditions: If set, verifies that the input matrices commute
              and are respectively symmetric and diagonal descending.
  
      Returns:
          An orthogonal matrix P such that P.T @ symmetric_matrix @ P is diagonal
          and P.T @ diagonal_matrix @ P = diagonal_matrix (up to tolerance).
  
      Raises:
          ValueError: Matrices don't meet preconditions (e.g. not symmetric).
      """; 42, identifier:check_preconditions; 43, block; 44, function_name:similar_singular; 45, parameters; 46, block; 47, assignment; 48, assignment; 49, pattern_list; 50, identifier:ranges; 51, block; 52, identifier:p; 53, attribute; 54, attribute; 55, identifier:float; 56, identifier:float; 57, identifier:bool; 58, if_statement; 59, if_statement; 60, if_statement; 61, identifier:i; 62, identifier:j; 63, return_statement; 64, identifier:ranges; 65, call; 66, identifier:p; 67, call; 68, identifier:start; 69, identifier:end; 70, expression_statement; 71, expression_statement; 72, identifier:np; 73, identifier:ndarray; 74, identifier:np; 75, identifier:ndarray; 76, parenthesized_expression; 77, block; 78, parenthesized_expression; 79, block; 80, not_operator; 81, block; 82, call; 83, identifier:_contiguous_groups; 84, argument_list; 85, attribute; 86, argument_list; 87, assignment; 88, assignment; 89, boolean_operator; 90, raise_statement; 91, boolean_operator; 92, raise_statement; 93, call; 94, raise_statement; 95, attribute; 96, argument_list; 97, subscript; 98, identifier:similar_singular; 99, identifier:np; 100, identifier:zeros; 101, attribute; 102, keyword_argument; 103, identifier:block; 104, subscript; 105, subscript; 106, call; 107, call; 108, not_operator; 109, call; 110, boolean_operator; 111, call; 112, call; 113, attribute; 114, argument_list; 115, call; 116, identifier:np; 117, identifier:allclose; 118, subscript; 119, subscript; 120, keyword_argument; 121, attribute; 122, integer:0; 123, identifier:symmetric_matrix; 124, identifier:shape; 125, identifier:dtype; 126, attribute; 127, identifier:symmetric_matrix; 128, slice; 129, slice; 130, identifier:p; 131, slice; 132, slice; 133, identifier:diagonalize_real_symmetric_matrix; 134, argument_list; 135, attribute; 136, argument_list; 137, call; 138, identifier:ValueError; 139, argument_list; 140, not_operator; 141, call; 142, attribute; 143, argument_list; 144, identifier:ValueError; 145, argument_list; 146, identifier:predicates; 147, identifier:commutes; 148, identifier:diagonal_matrix; 149, identifier:symmetric_matrix; 150, keyword_argument; 151, keyword_argument; 152, identifier:ValueError; 153, argument_list; 154, identifier:diagonal_matrix; 155, identifier:i; 156, identifier:i; 157, identifier:diagonal_matrix; 158, identifier:j; 159, identifier:j; 160, identifier:rtol; 161, identifier:rtol; 162, identifier:diagonal_matrix; 163, identifier:shape; 164, identifier:np; 165, identifier:float64; 166, identifier:start; 167, identifier:end; 168, identifier:start; 169, identifier:end; 170, identifier:start; 171, identifier:end; 172, identifier:start; 173, identifier:end; 174, identifier:block; 175, keyword_argument; 176, keyword_argument; 177, identifier:np; 178, identifier:any; 179, call; 180, attribute; 181, argument_list; 182, string; 183, call; 184, attribute; 185, argument_list; 186, identifier:np; 187, identifier:any; 188, comparison_operator:diagonal_matrix[:-1, :-1] < diagonal_matrix[1:, 1:]; 189, string; 190, identifier:rtol; 191, identifier:rtol; 192, identifier:atol; 193, identifier:atol; 194, string; 195, identifier:rtol; 196, identifier:rtol; 197, identifier:atol; 198, identifier:atol; 199, attribute; 200, argument_list; 201, identifier:predicates; 202, identifier:is_hermitian; 203, identifier:symmetric_matrix; 204, keyword_argument; 205, keyword_argument; 206, string_content:symmetric_matrix must be real symmetric.; 207, attribute; 208, argument_list; 209, identifier:np; 210, identifier:any; 211, call; 212, subscript; 213, subscript; 214, string_content:diagonal_matrix must be real diagonal descending.; 215, string_content:Given matrices must commute.; 216, identifier:np; 217, identifier:imag; 218, identifier:symmetric_matrix; 219, identifier:rtol; 220, identifier:rtol; 221, identifier:atol; 222, identifier:atol; 223, identifier:predicates; 224, identifier:is_diagonal; 225, identifier:diagonal_matrix; 226, keyword_argument; 227, attribute; 228, argument_list; 229, identifier:diagonal_matrix; 230, slice; 231, slice; 232, identifier:diagonal_matrix; 233, slice; 234, slice; 235, identifier:atol; 236, identifier:atol; 237, identifier:np; 238, identifier:imag; 239, identifier:diagonal_matrix; 240, unary_operator; 241, unary_operator; 242, integer:1; 243, integer:1; 244, integer:1; 245, integer:1
code: def diagonalize_real_symmetric_and_sorted_diagonal_matrices(
          symmetric_matrix: np.ndarray,
          diagonal_matrix: np.ndarray,
          *,
          rtol: float = 1e-5,
          atol: float = 1e-8,
          check_preconditions: bool = True) -> np.ndarray:
      """Returns an orthogonal matrix that diagonalizes both given matrices.
  
      The given matrices must commute.
      Guarantees that the sorted diagonal matrix is not permuted by the
      diagonalization (except for nearly-equal values).
  
      Args:
          symmetric_matrix: A real symmetric matrix.
          diagonal_matrix: A real diagonal matrix with entries along the diagonal
              sorted into descending order.
          rtol: Relative numeric error threshold.
          atol: Absolute numeric error threshold.
          check_preconditions: If set, verifies that the input matrices commute
              and are respectively symmetric and diagonal descending.
  
      Returns:
          An orthogonal matrix P such that P.T @ symmetric_matrix @ P is diagonal
          and P.T @ diagonal_matrix @ P = diagonal_matrix (up to tolerance).
  
      Raises:
          ValueError: Matrices don't meet preconditions (e.g. not symmetric).
      """
  
      # Verify preconditions.
      if check_preconditions:
          if (np.any(np.imag(symmetric_matrix)) or
                  not predicates.is_hermitian(symmetric_matrix,
                                              rtol=rtol,
                                              atol=atol)):
              raise ValueError('symmetric_matrix must be real symmetric.')
          if (not predicates.is_diagonal(diagonal_matrix, atol=atol) or
                  np.any(np.imag(diagonal_matrix)) or
                  np.any(diagonal_matrix[:-1, :-1] < diagonal_matrix[1:, 1:])):
              raise ValueError(
                  'diagonal_matrix must be real diagonal descending.')
          if not predicates.commutes(diagonal_matrix,
                                     symmetric_matrix,
                                     rtol=rtol,
                                     atol=atol):
              raise ValueError('Given matrices must commute.')
  
      def similar_singular(i, j):
          return np.allclose(diagonal_matrix[i, i],
                              diagonal_matrix[j, j], rtol=rtol)
  
      # Because the symmetric matrix commutes with the diagonal singulars matrix,
      # the symmetric matrix should be block-diagonal with a block boundary
      # wherever the singular values happen change. So we can use the singular
      # values to extract blocks that can be independently diagonalized.
      ranges = _contiguous_groups(diagonal_matrix.shape[0], similar_singular)
  
      # Build the overall diagonalization by diagonalizing each block.
      p = np.zeros(symmetric_matrix.shape, dtype=np.float64)
      for start, end in ranges:
          block = symmetric_matrix[start:end, start:end]
          p[start:end, start:end] = diagonalize_real_symmetric_matrix(
              block, rtol=rtol, atol=atol)
  
      return p