예제 #1
0
    def setUpClass(cls):
        """Initialize some ZIP outputs with different base powers."""

        # Use 120V nominal.
        cls.v_n = V_N

        # Use logarithmically varying S_n
        cls.s_n = [1, 10, 100, 1000]

        # Use four sets of ZIP coefficients that can use the default
        # initial parameters.
        cls.zip = [ZIP_CFL_42W, ZIP_LCD, ZIP_CFL_13W, ZIP_FAN]

        # Initialize results for the 4 coefficients.
        cls.results = [pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]

        # Sweep voltage from 90% to 110% of nominal.
        cls.v = V_SWEEP

        # Loop and create output
        for i in range(len(cls.zip)):
            p, q = zip._zip_model(v=cls.v, v_n=cls.v_n, s_n=cls.s_n[i],
                                  zip_terms=cls.zip[i])

            # Get into format for calling zip_fit.
            vpq = pd.DataFrame({'v': cls.v, 'p': p, 'q': q})

            cls.results[i] = vpq
예제 #2
0
 def setUpClass(cls):
     cls.v_n = V_N
     cls.s_n = S_N
     cls.v = V_SWEEP
     p, q = zip._zip_model(v=cls.v, v_n=cls.v_n, s_n=cls.s_n,
                           zip_terms=zip.PAR_0)
     cls.vpq = pd.DataFrame({'v': cls.v, 'p': p, 'q': q})
예제 #3
0
    def run_fit(self, key):
        """Helper to perform the fit and tests."""
        # Grab attributes.
        vpq_bar = getattr(self, key)['vpq_bar']
        p_expected = getattr(self, key)['p']
        q_expected = getattr(self, key)['q']
        # zip_terms = getattr(self, key)['zip_terms']

        #
        result = zip._zip_fit_slsqp(vpq_bar=vpq_bar)

        with self.subTest('{}, success'.format(key)):
            self.assertTrue(result.success)

        p_actual, q_actual = zip._zip_model(v=self.v, v_n=self.v_n,
                                            s_n=self.s_n, zip_terms=result.x)

        with self.subTest('{}, p'.format(key)):
            np.testing.assert_allclose(p_actual, p_expected, rtol=R_TOL_P,
                                       atol=A_TOL)

        # If all the Q values are essentially 0 (like for the
        # incandescent bulb), we need to take a different approach.
        if not np.allclose(q_expected, np.zeros_like(q_expected), atol=A_TOL_0,
                           rtol=0):
            rtol = R_TOL_Q
            atol = A_TOL
        else:
            rtol = 0
            atol = 0.05

        with self.subTest('{}, q'.format(key)):
            np.testing.assert_allclose(q_actual, q_expected, rtol=rtol,
                                       atol=atol)
예제 #4
0
    def setUpClass(cls):
        """Initialize all our expected results."""

        # Use 120V nominal.
        cls.v_n = V_N

        # We'll use a 1000VA base.
        cls.s_n = S_N

        # Sweep voltage from 90% to 110% of nominal.
        cls.v = V_SWEEP

        # Loop and assign.
        for key, value in ZIP_DICT.items():
            # Compute P and Q for the given model.
            p, q = zip._zip_model(v=cls.v, v_n=cls.v_n, s_n=cls.s_n,
                                  zip_terms=value)

            # Normalize.
            vpq_bar = zip._get_vpq_bar(
                vpq=pd.DataFrame({'v': cls.v, 'p': p, 'q': q}), v_n=cls.v_n,
                s_n=cls.s_n)

            setattr(cls, key, {'vpq_bar': vpq_bar,
                               'p': p, 'q': q})
예제 #5
0
    def test_zip_model(self):
        """Simple test of _zip_model to ensure accuracy.
        """
        v = np.array([10])
        v_n = np.array([11])
        s_n = 100
        zip_terms = np.array([1/3, np.pi/4, 1/3, np.pi/4, 1/3, np.pi/4])

        # Get our p and q
        p_actual, q_actual = zip._zip_model(v=v, v_n=v_n, s_n=s_n,
                                            zip_terms=zip_terms)

        # sin and cos of pi/4 evaluate to sqrt(2)/2
        r22 = 2 ** 0.5 / 2
        # Hard-coding to make the test less maintainable but prevent
        # myself from copying from the function itself.
        p_expected = 100 * np.array([
            (10 ** 2) / (11 ** 2) * (1/3) * r22 + 10/11 * (1/3) * r22
            + (1/3) * r22
        ])
        # Since we used an angle of pi/4, p and q should be equal.
        q_expected = p_expected

        # Test.
        np.testing.assert_array_almost_equal(p_expected, p_actual)
        np.testing.assert_array_almost_equal(q_expected, q_actual)
예제 #6
0
    def test_zip_obj_and_jac_zero_error(self):
        """Given the correct zip_terms, our objective and Jacobian
        should be zero (to within reasonable rounding error)."""
        p, q = zip._zip_model(v=V_SWEEP, v_n=V_N, s_n=S_N,
                              zip_terms=zip.PAR_0)

        vpq = pd.DataFrame({'v': V_SWEEP, 'p': p, 'q': q})
        vpq_bar = zip._get_vpq_bar(vpq=vpq, v_n=V_N, s_n=S_N)

        obj, jac = zip._zip_obj_and_jac(zip_terms=zip.PAR_0,
                                        v_s=vpq_bar['v_bar'].values**2,
                                        v_bar=vpq_bar['v_bar'].values,
                                        p_bar=vpq_bar['p_bar'].values,
                                        q_bar=vpq_bar['q_bar'].values)

        # Our p and q are on the order of several hundred, so matching
        # to within 1 decimal place is acceptable.
        self.assertAlmostEqual(0, obj)
        np.testing.assert_allclose(jac, 0, rtol=0, atol=1e-10)