Esempio n. 1
0
    def test_characterize_function(self):
        with self.assertRaises(ValueError):
            util.characterize_function([1,2,-1],
                                       [1,1,1])

        fc, slopes = util.characterize_function([1,2,3],
                                                [1,1,1])
        self.assertEqual(fc, 1) # affine
        self.assertEqual(slopes, [0,0])

        fc, slopes = util.characterize_function([1,2,3],
                                                [1,0,1])
        self.assertEqual(fc, 2) # convex
        self.assertEqual(slopes, [-1,1])

        fc, slopes = util.characterize_function([1,2,3],
                                                [1,2,1])
        self.assertEqual(fc, 3) # concave
        self.assertEqual(slopes, [1,-1])

        fc, slopes = util.characterize_function([1,1,2],
                                                [1,2,1])
        self.assertEqual(fc, 4) # step
        self.assertEqual(slopes, [None,-1])

        fc, slopes = util.characterize_function([1,2,3,4],
                                                [1,2,1,2])
        self.assertEqual(fc, 5) # none of the above
        self.assertEqual(slopes, [1,-1,1])
Esempio n. 2
0
    def validate(self,
                 equal_slopes_tolerance=1e-6):
        """
        Validate this piecewise linear function by verifying
        various properties of the breakpoints and values
        lists (e.g., that the list of breakpoints is
        nondecreasing).

        Args:
            equal_slopes_tolerance (float): Tolerance used
                check if consecutive slopes are nearly
                equal. If any are found, validation will
                fail. Default is 1e-6.

        Returns:
            int:
                a function characterization code (see \
                :func:`util.characterize_function`)

        Raises:
            PiecewiseValidationError: if validation fails
        """

        breakpoints = [_value(x) for x in self._breakpoints]
        values = [_value(x) for x in self._values]
        if not is_nondecreasing(breakpoints):
            raise PiecewiseValidationError(
                "The list of breakpoints is not nondecreasing: %s"
                % (str(breakpoints)))

        ftype, slopes = characterize_function(breakpoints, values)
        for i in range(1, len(slopes)):
            if (slopes[i-1] is not None) and \
               (slopes[i] is not None) and \
               (abs(slopes[i-1] - slopes[i]) <= equal_slopes_tolerance):
                raise PiecewiseValidationError(
                    "Piecewise function validation detected slopes "
                    "of consecutive line segments to be within %s "
                    "of one another. This may cause numerical issues. "
                    "To avoid this error, set the 'equal_slopes_tolerance' "
                    "keyword to a smaller value or disable validation."
                    % (equal_slopes_tolerance))

        return ftype