nodes: 0, module; 1, function_definition; 2, function_name:get_points_and_weights; 3, parameters; 4, block; 5, default_parameter; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, expression_statement; 11, expression_statement; 12, expression_statement; 13, expression_statement; 14, expression_statement; 15, expression_statement; 16, expression_statement; 17, expression_statement; 18, expression_statement; 19, expression_statement; 20, expression_statement; 21, expression_statement; 22, expression_statement; 23, expression_statement; 24, expression_statement; 25, return_statement; 26, identifier:w_func; 27, lambda; 28, identifier:left; 29, unary_operator; 30, identifier:right; 31, float:1.0; 32, identifier:num_points; 33, integer:5; 34, identifier:n; 35, integer:4096; 36, comment:"""Quadratude points and weights for a weighting function.
  
      Points and weights for approximating the integral 
          I = \int_left^right f(x) w(x) dx
      given the weighting function w(x) using the approximation
          I ~ w_i f(x_i)
  
      Args:
          w_func: The weighting function w(x). Must be a function that takes
              one argument and is valid over the open interval (left, right).
          left: The left boundary of the interval
          right: The left boundary of the interval
          num_points: number of integration points to return
          n: the number of points to evaluate w_func at.
  
      Returns:
          A tuple (points, weights) where points is a sorted array of the
          points x_i and weights gives the corresponding weights w_i.
      """; 37, assignment; 38, assignment; 39, assignment; 40, assignment; 41, assignment; 42, assignment; 43, assignment; 44, augmented_assignment; 45, augmented_assignment; 46, assignment; 47, assignment; 48, assignment; 49, assignment; 50, assignment; 51, tuple; 52, lambda_parameters; 53, call; 54, float:1.0; 55, identifier:dx; 56, binary_operator:(float(right)-left)/n; 57, identifier:z; 58, call; 59, identifier:w; 60, binary_operator:dx*w_func(z); 61, tuple_pattern; 62, call; 63, identifier:alpha; 64, identifier:a; 65, identifier:beta; 66, call; 67, identifier:J; 68, call; 69, identifier:J; 70, call; 71, identifier:J; 72, call; 73, tuple_pattern; 74, call; 75, identifier:ind; 76, call; 77, identifier:points; 78, subscript; 79, identifier:weights; 80, binary_operator:v[0,:]**2 * w.sum(); 81, identifier:weights; 82, subscript; 83, identifier:points; 84, identifier:weights; 85, identifier:x; 86, attribute; 87, argument_list; 88, parenthesized_expression; 89, identifier:n; 90, attribute; 91, argument_list; 92, identifier:dx; 93, call; 94, identifier:a; 95, identifier:b; 96, identifier:discrete_gautschi; 97, argument_list; 98, attribute; 99, argument_list; 100, attribute; 101, argument_list; 102, attribute; 103, argument_list; 104, attribute; 105, argument_list; 106, identifier:points; 107, identifier:v; 108, attribute; 109, argument_list; 110, attribute; 111, argument_list; 112, identifier:points; 113, identifier:ind; 114, binary_operator:v[0,:]**2; 115, call; 116, identifier:weights; 117, identifier:ind; 118, identifier:np; 119, identifier:ones; 120, attribute; 121, binary_operator:float(right)-left; 122, identifier:np; 123, identifier:hstack; 124, call; 125, identifier:w_func; 126, argument_list; 127, identifier:z; 128, identifier:w; 129, identifier:num_points; 130, identifier:np; 131, identifier:sqrt; 132, identifier:b; 133, identifier:np; 134, identifier:diag; 135, identifier:alpha; 136, identifier:np; 137, identifier:diag; 138, identifier:beta; 139, keyword_argument; 140, identifier:np; 141, identifier:diag; 142, identifier:beta; 143, keyword_argument; 144, attribute; 145, identifier:eigh; 146, identifier:J; 147, identifier:points; 148, identifier:argsort; 149, subscript; 150, integer:2; 151, attribute; 152, argument_list; 153, identifier:x; 154, identifier:shape; 155, call; 156, identifier:left; 157, attribute; 158, argument_list; 159, identifier:z; 160, identifier:k; 161, unary_operator; 162, identifier:k; 163, integer:1; 164, identifier:np; 165, identifier:linalg; 166, identifier:v; 167, integer:0; 168, slice; 169, identifier:w; 170, identifier:sum; 171, identifier:float; 172, argument_list; 173, identifier:np; 174, identifier:linspace; 175, binary_operator:left+0.5*dx; 176, binary_operator:right-0.5*dx; 177, identifier:n; 178, integer:1; 179, identifier:right; 180, identifier:left; 181, binary_operator:0.5*dx; 182, identifier:right; 183, binary_operator:0.5*dx; 184, float:0.5; 185, identifier:dx; 186, float:0.5; 187, identifier:dx
code: def get_points_and_weights(w_func=lambda x : np.ones(x.shape), 
      left=-1.0, right=1.0, num_points=5, n=4096):
      """Quadratude points and weights for a weighting function.
  
      Points and weights for approximating the integral 
          I = \int_left^right f(x) w(x) dx
      given the weighting function w(x) using the approximation
          I ~ w_i f(x_i)
  
      Args:
          w_func: The weighting function w(x). Must be a function that takes
              one argument and is valid over the open interval (left, right).
          left: The left boundary of the interval
          right: The left boundary of the interval
          num_points: number of integration points to return
          n: the number of points to evaluate w_func at.
  
      Returns:
          A tuple (points, weights) where points is a sorted array of the
          points x_i and weights gives the corresponding weights w_i.
      """
      
      dx = (float(right)-left)/n
      z = np.hstack(np.linspace(left+0.5*dx, right-0.5*dx, n))
      w = dx*w_func(z)  
     
      (a, b) = discrete_gautschi(z, w, num_points)
      alpha = a
      beta = np.sqrt(b)
      
      J = np.diag(alpha)
      J += np.diag(beta, k=-1)
      J += np.diag(beta, k=1)    
      
      (points,v) = np.linalg.eigh(J)
      ind = points.argsort()
      points = points[ind]
      weights = v[0,:]**2 * w.sum()
      weights = weights[ind]
      
      return (points, weights)