def __init__(self, num_nodes, tleft=0, tright=1): """ Initialization routine for an collocation object Args: num_nodes (int): number of collocation nodes tleft (float): left interval point tright (float): right interval point """ if not num_nodes > 0: raise CollocationError( 'At least one quadrature node required, got %s' % num_nodes) if not tleft < tright: raise CollocationError( 'Interval boundaries are corrupt, got %s and %s' % (tleft, tright)) self.logger = logging.getLogger('collocation') # Set number of nodes, left and right interval boundaries self.num_nodes = num_nodes self.tleft = tleft self.tright = tright # Dummy values for the rest self.nodes = None self.weights = None self.Qmat = None self.Smat = None self.delta_m = None self.right_is_node = None self.left_is_node = None
def _getWeights(self, a, b): """ Computes weights using custom barycentric interpolation Args: a (float): left interval boundary b (float): right interval boundary Returns: numpy.ndarray: weights of the collocation formula given by the nodes """ if self.nodes is None: raise CollocationError("Need nodes before computing weights, got %s" % self.nodes) circ_one = np.zeros(self.num_nodes) circ_one[0] = 1.0 tcks = [] for i in range(self.num_nodes): # This is where the custom BarycentricInterpolator is called tcks.append(MyBarycentricInterpolator(self.nodes, np.roll(circ_one, i), self.fh_weights)) weights = np.zeros(self.num_nodes) for i in range(self.num_nodes): weights[i] = quad(tcks[i], a, b, epsabs=1e-14)[0] return weights
def evaluate(weights, data): """ Evaluates the quadrature over the full interval Args: weights (numpy.ndarray): array of quadrature weights for the full interval data (numpy.ndarray): f(x) to be integrated Returns: numpy.ndarray: integral over f(x) between tleft and tright """ if not np.size(weights) == np.size(data): raise CollocationError("Input size does not match number of weights, but is %s" % np.size(data)) return np.dot(weights, data)
def __init__(self, num_nodes, tleft, tright): """ Initialization Args: num_nodes: number of nodes tleft (float): left interval boundary (usually 0) tright (float): right interval boundary (usually 1) """ if type(num_nodes) is int: max_d = 15 nnodes = num_nodes else: if type(num_nodes) is not tuple: raise ParameterError('Expecting int or tuple for num_nodes parameter, got %s' % type(num_nodes)) if len(num_nodes) != 2: raise ParameterError('Expecting 1 or 2 arguments for num_nodes, got %s' % num_nodes) if type(num_nodes[0]) is not int: raise ParameterError('Expecting int type for first num_nodes argument, got %s' % type(num_nodes[0])) if type(num_nodes[1]) is not int: raise ParameterError('Expecting int type for second num_nodes argument, got %s' % type(num_nodes[1])) max_d = num_nodes[1] nnodes = num_nodes[0] if nnodes < 2: raise CollocationError("Number of nodes should be at least 2 for equidistant, but is %d" % num_nodes) super(Equidistant, self).__init__(nnodes, tleft, tright) self.order = self.num_nodes self.nodes = self._getNodes d = min(self.num_nodes - 1, max_d) self.fh_weights = self._getFHWeights(d) self.weights = self._getWeights(tleft, tright) self.Qmat = self._gen_Qmatrix self.Smat = self._gen_Smatrix self.delta_m = self._gen_deltas self.left_is_node = True self.right_is_node = True
def __init__(self, num_nodes, tleft, tright): """ Initialization Args: num_nodes (int): number of nodes tleft (float): left interval boundary (usually 0) tright (float): right interval boundary (usually 1) """ super(CollGaussRadau_Right, self).__init__(num_nodes, tleft, tright) if num_nodes < 2: raise CollocationError("Number of nodes should be at least 2 for Gauss-Radau, but is %d" % num_nodes) self.order = 2 * self.num_nodes - 1 self.nodes = self._getNodes self.weights = self._getWeights(tleft, tright) self.Qmat = self._gen_Qmatrix self.Smat = self._gen_Smatrix self.delta_m = self._gen_deltas self.left_is_node = False self.right_is_node = True
def __init__(self, num_nodes, tleft, tright): """ Initialization Args: num_nodes (int): number of nodes tleft (float): left interval boundary (usually 0) tright (float): right interval boundary (usually 1) """ super(EquidistantSpline_Right, self).__init__(num_nodes, tleft, tright) if num_nodes < 2: raise CollocationError("Number of nodes should be at least 2 for equidist. splines, but is %d" % num_nodes) # This is a fixed order since we are using splines here! No spectral accuracy! self.order = min(num_nodes - 1, 3) # We need: 1<=order<=5 and order < num_nodes self.nodes = self._getNodes self.weights = self._getWeights(tleft, tright) self.Qmat = self._gen_Qmatrix self.Smat = self._gen_Smatrix self.delta_m = self._gen_deltas self.left_is_node = False self.right_is_node = True
def __init__(self, num_nodes, tleft, tright): """ Initialization Args: num_nodes (int): number of nodes tleft (float): left interval boundary (usually 0) tright (float): right interval boundary (usually 1) """ super(EquidistantInner, self).__init__(num_nodes, tleft, tright) if num_nodes < 1: raise CollocationError( "Number of nodes should be at least 1 for equidistant inner, but is %d" % num_nodes) self.order = self.num_nodes self.nodes = self._getNodes self.weights = self._getWeights(tleft, tright) self.Qmat = self._gen_Qmatrix self.Smat = self._gen_Smatrix self.delta_m = self._gen_deltas self.left_is_node = False self.right_is_node = False