nodes: 0, module; 1, function_definition; 2, function_name:schwarz; 3, parameters; 4, block; 5, identifier:A; 6, identifier:x; 7, identifier:b; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, if_statement; 18, comment:# If no subdomains are defined, default is to use the sparsity pattern of A; 19, comment:# to define the overlapping regions; 20, expression_statement; 21, if_statement; 22, comment:# Call C code, need to make sure that subdomains are sorted and unique; 23, for_statement; 24, identifier:iterations; 25, integer:1; 26, identifier:subdomain; 27, None; 28, identifier:subdomain_ptr; 29, None; 30, identifier:inv_subblock; 31, None; 32, identifier:inv_subblock_ptr; 33, None; 34, identifier:sweep; 35, string; 36, comment:"""Perform Overlapping multiplicative Schwarz on the linear system Ax=b.
  
      Parameters
      ----------
      A : csr_matrix, bsr_matrix
          Sparse NxN matrix
      x : ndarray
          Approximate solution (length N)
      b : ndarray
          Right-hand side (length N)
      iterations : int
          Number of iterations to perform
      subdomain : int array
          Linear array containing each subdomain's elements
      subdomain_ptr : int array
          Pointer in subdomain, such that
          subdomain[subdomain_ptr[i]:subdomain_ptr[i+1]]]
          contains the _sorted_ indices in subdomain i
      inv_subblock : int_array
          Linear array containing each subdomain's
          inverted diagonal block of A
      inv_subblock_ptr : int array
          Pointer in inv_subblock, such that
          inv_subblock[inv_subblock_ptr[i]:inv_subblock_ptr[i+1]]]
          contains the inverted diagonal block of A for the
          i-th subdomain in _row_ major order
      sweep : {'forward','backward','symmetric'}
          Direction of sweep
  
      Returns
      -------
      Nothing, x will be modified in place.
  
      Notes
      -----
      If subdomains is None, then a point-wise iteration takes place,
      with the overlapping region defined by each degree-of-freedom's
      neighbors in the matrix graph.
  
      If subdomains is not None, but subblocks is, then the subblocks
      are formed internally.
  
      Currently only supports CSR matrices
  
      Examples
      --------
      >>> # Use Overlapping Schwarz as a Stand-Alone Solver
      >>> from pyamg.relaxation.relaxation import schwarz
      >>> from pyamg.gallery import poisson
      >>> from pyamg.util.linalg import norm
      >>> import numpy as np
      >>> A = poisson((10,10), format='csr')
      >>> x0 = np.zeros((A.shape[0],1))
      >>> b = np.ones((A.shape[0],1))
      >>> schwarz(A, x0, b, iterations=10)
      >>> print norm(b-A*x0)
      0.126326160522
      >>> #
      >>> # Schwarz as the Multigrid Smoother
      >>> from pyamg import smoothed_aggregation_solver
      >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
      ...         coarse_solver='pinv2', max_coarse=50,
      ...         presmoother='schwarz',
      ...         postsmoother='schwarz')
      >>> x0=np.zeros((A.shape[0],1))
      >>> residuals=[]
      >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)
  
      """; 37, assignment; 38, call; 39, boolean_operator; 40, block; 41, assignment; 42, comparison_operator:sweep == 'forward'; 43, block; 44, elif_clause; 45, elif_clause; 46, else_clause; 47, identifier:iter; 48, call; 49, block; 50, string_content:forward; 51, pattern_list; 52, call; 53, attribute; 54, argument_list; 55, comparison_operator:subdomain is None; 56, comparison_operator:inv_subblock is not None; 57, raise_statement; 58, tuple_pattern; 59, line_continuation:\; 60, call; 61, identifier:sweep; 62, string; 63, expression_statement; 64, comparison_operator:sweep == 'backward'; 65, block; 66, comparison_operator:sweep == 'symmetric'; 67, block; 68, block; 69, identifier:range; 70, argument_list; 71, expression_statement; 72, identifier:A; 73, identifier:x; 74, identifier:b; 75, identifier:make_system; 76, argument_list; 77, identifier:A; 78, identifier:sort_indices; 79, identifier:subdomain; 80, None; 81, identifier:inv_subblock; 82, None; 83, call; 84, identifier:subdomain; 85, identifier:subdomain_ptr; 86, identifier:inv_subblock; 87, identifier:inv_subblock_ptr; 88, identifier:schwarz_parameters; 89, argument_list; 90, string_content:forward; 91, assignment; 92, identifier:sweep; 93, string; 94, expression_statement; 95, identifier:sweep; 96, string; 97, for_statement; 98, return_statement; 99, raise_statement; 100, identifier:iterations; 101, call; 102, identifier:A; 103, identifier:x; 104, identifier:b; 105, keyword_argument; 106, identifier:ValueError; 107, argument_list; 108, identifier:A; 109, identifier:subdomain; 110, identifier:subdomain_ptr; 111, identifier:inv_subblock; 112, identifier:inv_subblock_ptr; 113, pattern_list; 114, expression_list; 115, string_content:backward; 116, assignment; 117, string_content:symmetric; 118, identifier:iter; 119, call; 120, block; 121, call; 122, attribute; 123, argument_list; 124, identifier:formats; 125, list; 126, string:"inv_subblock must be None if subdomain is None"; 127, identifier:row_start; 128, identifier:row_stop; 129, identifier:row_step; 130, integer:0; 131, binary_operator:subdomain_ptr.shape[0]-1; 132, integer:1; 133, pattern_list; 134, expression_list; 135, identifier:range; 136, argument_list; 137, expression_statement; 138, expression_statement; 139, identifier:ValueError; 140, argument_list; 141, identifier:amg_core; 142, identifier:overlapping_schwarz_csr; 143, attribute; 144, attribute; 145, attribute; 146, identifier:x; 147, identifier:b; 148, identifier:inv_subblock; 149, identifier:inv_subblock_ptr; 150, identifier:subdomain; 151, identifier:subdomain_ptr; 152, binary_operator:subdomain_ptr.shape[0]-1; 153, subscript; 154, identifier:row_start; 155, identifier:row_stop; 156, identifier:row_step; 157, string; 158, subscript; 159, integer:1; 160, identifier:row_start; 161, identifier:row_stop; 162, identifier:row_step; 163, binary_operator:subdomain_ptr.shape[0]-2; 164, unary_operator; 165, unary_operator; 166, identifier:iterations; 167, call; 168, call; 169, string:"valid sweep directions are 'forward',\
                            'backward', and 'symmetric'"; 170, identifier:A; 171, identifier:indptr; 172, identifier:A; 173, identifier:indices; 174, identifier:A; 175, identifier:data; 176, subscript; 177, integer:1; 178, attribute; 179, integer:0; 180, string_content:csr; 181, attribute; 182, integer:0; 183, subscript; 184, integer:2; 185, integer:1; 186, integer:1; 187, identifier:schwarz; 188, argument_list; 189, identifier:schwarz; 190, argument_list; 191, attribute; 192, integer:0; 193, identifier:A; 194, identifier:shape; 195, identifier:subdomain_ptr; 196, identifier:shape; 197, attribute; 198, integer:0; 199, identifier:A; 200, identifier:x; 201, identifier:b; 202, keyword_argument; 203, keyword_argument; 204, keyword_argument; 205, keyword_argument; 206, keyword_argument; 207, keyword_argument; 208, identifier:A; 209, identifier:x; 210, identifier:b; 211, keyword_argument; 212, keyword_argument; 213, keyword_argument; 214, keyword_argument; 215, keyword_argument; 216, keyword_argument; 217, identifier:subdomain_ptr; 218, identifier:shape; 219, identifier:subdomain_ptr; 220, identifier:shape; 221, identifier:iterations; 222, integer:1; 223, identifier:subdomain; 224, identifier:subdomain; 225, identifier:subdomain_ptr; 226, identifier:subdomain_ptr; 227, identifier:inv_subblock; 228, identifier:inv_subblock; 229, identifier:inv_subblock_ptr; 230, identifier:inv_subblock_ptr; 231, identifier:sweep; 232, string; 233, identifier:iterations; 234, integer:1; 235, identifier:subdomain; 236, identifier:subdomain; 237, identifier:subdomain_ptr; 238, identifier:subdomain_ptr; 239, identifier:inv_subblock; 240, identifier:inv_subblock; 241, identifier:inv_subblock_ptr; 242, identifier:inv_subblock_ptr; 243, identifier:sweep; 244, string; 245, string_content:forward; 246, string_content:backward
code: def schwarz(A, x, b, iterations=1, subdomain=None, subdomain_ptr=None,
              inv_subblock=None, inv_subblock_ptr=None, sweep='forward'):
      """Perform Overlapping multiplicative Schwarz on the linear system Ax=b.
  
      Parameters
      ----------
      A : csr_matrix, bsr_matrix
          Sparse NxN matrix
      x : ndarray
          Approximate solution (length N)
      b : ndarray
          Right-hand side (length N)
      iterations : int
          Number of iterations to perform
      subdomain : int array
          Linear array containing each subdomain's elements
      subdomain_ptr : int array
          Pointer in subdomain, such that
          subdomain[subdomain_ptr[i]:subdomain_ptr[i+1]]]
          contains the _sorted_ indices in subdomain i
      inv_subblock : int_array
          Linear array containing each subdomain's
          inverted diagonal block of A
      inv_subblock_ptr : int array
          Pointer in inv_subblock, such that
          inv_subblock[inv_subblock_ptr[i]:inv_subblock_ptr[i+1]]]
          contains the inverted diagonal block of A for the
          i-th subdomain in _row_ major order
      sweep : {'forward','backward','symmetric'}
          Direction of sweep
  
      Returns
      -------
      Nothing, x will be modified in place.
  
      Notes
      -----
      If subdomains is None, then a point-wise iteration takes place,
      with the overlapping region defined by each degree-of-freedom's
      neighbors in the matrix graph.
  
      If subdomains is not None, but subblocks is, then the subblocks
      are formed internally.
  
      Currently only supports CSR matrices
  
      Examples
      --------
      >>> # Use Overlapping Schwarz as a Stand-Alone Solver
      >>> from pyamg.relaxation.relaxation import schwarz
      >>> from pyamg.gallery import poisson
      >>> from pyamg.util.linalg import norm
      >>> import numpy as np
      >>> A = poisson((10,10), format='csr')
      >>> x0 = np.zeros((A.shape[0],1))
      >>> b = np.ones((A.shape[0],1))
      >>> schwarz(A, x0, b, iterations=10)
      >>> print norm(b-A*x0)
      0.126326160522
      >>> #
      >>> # Schwarz as the Multigrid Smoother
      >>> from pyamg import smoothed_aggregation_solver
      >>> sa = smoothed_aggregation_solver(A, B=np.ones((A.shape[0],1)),
      ...         coarse_solver='pinv2', max_coarse=50,
      ...         presmoother='schwarz',
      ...         postsmoother='schwarz')
      >>> x0=np.zeros((A.shape[0],1))
      >>> residuals=[]
      >>> x = sa.solve(b, x0=x0, tol=1e-8, residuals=residuals)
  
      """
      A, x, b = make_system(A, x, b, formats=['csr'])
      A.sort_indices()
  
      if subdomain is None and inv_subblock is not None:
          raise ValueError("inv_subblock must be None if subdomain is None")
  
      # If no subdomains are defined, default is to use the sparsity pattern of A
      # to define the overlapping regions
      (subdomain, subdomain_ptr, inv_subblock, inv_subblock_ptr) = \
          schwarz_parameters(A, subdomain, subdomain_ptr,
                             inv_subblock, inv_subblock_ptr)
  
      if sweep == 'forward':
          row_start, row_stop, row_step = 0, subdomain_ptr.shape[0]-1, 1
      elif sweep == 'backward':
          row_start, row_stop, row_step = subdomain_ptr.shape[0]-2, -1, -1
      elif sweep == 'symmetric':
          for iter in range(iterations):
              schwarz(A, x, b, iterations=1, subdomain=subdomain,
                      subdomain_ptr=subdomain_ptr, inv_subblock=inv_subblock,
                      inv_subblock_ptr=inv_subblock_ptr, sweep='forward')
              schwarz(A, x, b, iterations=1, subdomain=subdomain,
                      subdomain_ptr=subdomain_ptr, inv_subblock=inv_subblock,
                      inv_subblock_ptr=inv_subblock_ptr, sweep='backward')
          return
      else:
          raise ValueError("valid sweep directions are 'forward',\
                            'backward', and 'symmetric'")
  
      # Call C code, need to make sure that subdomains are sorted and unique
      for iter in range(iterations):
          amg_core.overlapping_schwarz_csr(A.indptr, A.indices, A.data,
                                           x, b, inv_subblock, inv_subblock_ptr,
                                           subdomain, subdomain_ptr,
                                           subdomain_ptr.shape[0]-1, A.shape[0],
                                           row_start, row_stop, row_step)