Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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)
Пример #4
0
    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
Пример #5
0
    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
Пример #7
0
    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