nodes: 0, module; 1, function_definition; 2, function_name:_qr_factor_full; 3, parameters; 4, block; 5, identifier:a; 6, default_parameter; 7, expression_statement; 8, expression_statement; 9, comment:# Compute the packed Q and R matrix information.; 10, expression_statement; 11, comment:# Now we unpack. Start with the R matrix, which is easy: we just; 12, comment:# have to piece it together from the strict lower triangle of 'a'; 13, comment:# and the diagonal in 'rdiag'.; 14, expression_statement; 15, for_statement; 16, comment:# Now the Q matrix. It is the concatenation of n Householder; 17, comment:# transformations, each of which is defined by a row in the upper; 18, comment:# trapezoidal portion of 'a'. We extract the appropriate vector,; 19, comment:# construct the matrix for the Householder transform, and build up; 20, comment:# the Q matrix.; 21, expression_statement; 22, expression_statement; 23, for_statement; 24, return_statement; 25, identifier:dtype; 26, attribute; 27, comment:"""Compute the QR factorization of a matrix, with pivoting.
  
  Parameters:
  a     - An n-by-m arraylike, m >= n.
  dtype - (optional) The data type to use for computations.
          Default is np.float.
  
  Returns:
  q    - An m-by-m orthogonal matrix (q q^T = ident)
  r    - An n-by-m upper triangular matrix
  pmut - An n-element permutation vector
  
  The returned values will satisfy the equation
  
  np.dot(r, q) == a[:,pmut]
  
  The outputs are computed indirectly via the function
  _qr_factor_packed. If you need to compute q and r matrices in
  production code, there are faster ways to do it. This function is for
  testing _qr_factor_packed.
  
  The permutation vector pmut is a vector of the integers 0 through
  n-1. It sorts the rows of 'a' by their norms, so that the
  pmut[i]'th row of 'a' has the i'th biggest norm."""; 28, assignment; 29, assignment; 30, assignment; 31, identifier:i; 32, call; 33, block; 34, assignment; 35, assignment; 36, identifier:i; 37, call; 38, block; 39, expression_list; 40, identifier:np; 41, identifier:float; 42, pattern_list; 43, attribute; 44, pattern_list; 45, line_continuation:\; 46, call; 47, identifier:r; 48, call; 49, identifier:range; 50, argument_list; 51, expression_statement; 52, expression_statement; 53, identifier:q; 54, call; 55, identifier:v; 56, call; 57, identifier:range; 58, argument_list; 59, expression_statement; 60, expression_statement; 61, expression_statement; 62, expression_statement; 63, identifier:q; 64, identifier:r; 65, identifier:pmut; 66, identifier:n; 67, identifier:m; 68, identifier:a; 69, identifier:shape; 70, identifier:packed; 71, identifier:pmut; 72, identifier:rdiag; 73, identifier:acnorm; 74, identifier:_manual_qr_factor_packed; 75, argument_list; 76, attribute; 77, argument_list; 78, identifier:n; 79, assignment; 80, assignment; 81, attribute; 82, argument_list; 83, attribute; 84, argument_list; 85, identifier:n; 86, assignment; 87, assignment; 88, assignment; 89, assignment; 90, identifier:a; 91, identifier:dtype; 92, identifier:np; 93, identifier:zeros; 94, tuple; 95, subscript; 96, subscript; 97, subscript; 98, subscript; 99, identifier:np; 100, identifier:eye; 101, identifier:m; 102, identifier:np; 103, identifier:empty; 104, identifier:m; 105, subscript; 106, subscript; 107, subscript; 108, integer:0; 109, identifier:hhm; 110, binary_operator:np.eye(m) - 2 * np.outer(v, v) / np.dot(v, v); 111, identifier:q; 112, call; 113, identifier:n; 114, identifier:m; 115, identifier:r; 116, identifier:i; 117, slice; 118, identifier:packed; 119, identifier:i; 120, slice; 121, identifier:r; 122, identifier:i; 123, identifier:i; 124, identifier:rdiag; 125, identifier:i; 126, identifier:v; 127, slice; 128, identifier:packed; 129, identifier:i; 130, identifier:v; 131, slice; 132, call; 133, binary_operator:2 * np.outer(v, v) / np.dot(v, v); 134, attribute; 135, argument_list; 136, identifier:i; 137, identifier:i; 138, identifier:i; 139, attribute; 140, argument_list; 141, binary_operator:2 * np.outer(v, v); 142, call; 143, identifier:np; 144, identifier:dot; 145, identifier:hhm; 146, identifier:q; 147, identifier:np; 148, identifier:eye; 149, identifier:m; 150, integer:2; 151, call; 152, attribute; 153, argument_list; 154, attribute; 155, argument_list; 156, identifier:np; 157, identifier:dot; 158, identifier:v; 159, identifier:v; 160, identifier:np; 161, identifier:outer; 162, identifier:v; 163, identifier:v
code: def _qr_factor_full(a, dtype=np.float):
      """Compute the QR factorization of a matrix, with pivoting.
  
  Parameters:
  a     - An n-by-m arraylike, m >= n.
  dtype - (optional) The data type to use for computations.
          Default is np.float.
  
  Returns:
  q    - An m-by-m orthogonal matrix (q q^T = ident)
  r    - An n-by-m upper triangular matrix
  pmut - An n-element permutation vector
  
  The returned values will satisfy the equation
  
  np.dot(r, q) == a[:,pmut]
  
  The outputs are computed indirectly via the function
  _qr_factor_packed. If you need to compute q and r matrices in
  production code, there are faster ways to do it. This function is for
  testing _qr_factor_packed.
  
  The permutation vector pmut is a vector of the integers 0 through
  n-1. It sorts the rows of 'a' by their norms, so that the
  pmut[i]'th row of 'a' has the i'th biggest norm."""
  
      n, m = a.shape
  
      # Compute the packed Q and R matrix information.
  
      packed, pmut, rdiag, acnorm = \
          _manual_qr_factor_packed(a, dtype)
  
      # Now we unpack. Start with the R matrix, which is easy: we just
      # have to piece it together from the strict lower triangle of 'a'
      # and the diagonal in 'rdiag'.
  
      r = np.zeros((n, m))
  
      for i in range(n):
          r[i,:i] = packed[i,:i]
          r[i,i] = rdiag[i]
  
      # Now the Q matrix. It is the concatenation of n Householder
      # transformations, each of which is defined by a row in the upper
      # trapezoidal portion of 'a'. We extract the appropriate vector,
      # construct the matrix for the Householder transform, and build up
      # the Q matrix.
  
      q = np.eye(m)
      v = np.empty(m)
  
      for i in range(n):
          v[:] = packed[i]
          v[:i] = 0
  
          hhm = np.eye(m) - 2 * np.outer(v, v) / np.dot(v, v)
          q = np.dot(hhm, q)
  
      return q, r, pmut