<commit_before>from lcapy import *
from lcapy.cexpr import cExpr
import unittest


class LcapyTester(unittest.TestCase):

    """Unit tests for lcapy

    """

    def assertEqual2(self, ans1, ans2, comment):

        try:
            self.assertEqual(ans1, ans2, comment)
        except AssertionError as e:
            pprint(ans1)
            pprint(ans2)
            raise AssertionError(e)

    def test_rmul(self):

        self.assertEqual2((j * omega).__class__,  omegaExpr, "j * omega fail.")

    def test_Expr1(self):
        """Lcapy: check Expr

        """
        a = Expr(3)
        self.assertEqual2(a.N, Expr(3), "N incorrect.")
        self.assertEqual2(a.D, Expr(1), "D incorrect.")
        self.assertEqual2(a.real, Expr(3), "real incorrect.")
        self.assertEqual2(a.imag, Expr(0), "imag incorrect.")
        self.assertEqual2(a.magnitude, Expr(3), "magnitude incorrect.")
        self.assertEqual2(a.phase, Expr(0), "phase incorrect.")
        self.assertEqual2(a.phase_degrees, Expr(0), "phase incorrect.")
        self.assertEqual2(a.sign, Expr(1), "sign incorrect.")
        self.assertEqual2(-a.sign, Expr(-1), "sign incorrect.")

        a = Expr(3j)
        self.assertEqual2(a.N, Expr(3j), "N incorrect.")
        self.assertEqual2(a.D, Expr(1), "D incorrect.")
        self.assertEqual2(a.real, Expr(0), "real incorrect.")
        self.assertEqual2(a.imag, Expr(3), "imag incorrect.")        
        self.assertEqual2(a.magnitude, Expr(3), "magnitude incorrect.")
        self.assertEqual2(abs(a), Expr(3), "abs incorrect.")        
        self.assertEqual2(a.phase, Expr(pi / 2), "phase incorrect.")
        self.assertEqual2(a.phase_degrees, Expr(90), "phase incorrect.")
        self.assertEqual2(a.sign, Expr(j), "sign incorrect.")
        self.assertEqual2(-a.sign, Expr(-j), "sign incorrect.")        

        
    def test_sExpr1(self):
        """Lcapy: check sExpr

        """
        a = sExpr('(s+2)/(s-2)')
        self.assertEqual2(a.N, sExpr('s+2'), "N incorrect.")
        self.assertEqual2(a.D, sExpr('s-2'), "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), [-2], "zeros incorrect.")

        self.assertEqual2(a.partfrac(), 1 + 4 / (s - 2), "partfrac incorrect.")

        self.assertEqual(a.evaluate(1), -3.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate(-2), 0.0, "scalar evaluate incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 4 * exp(2 * t) * H(t) + DiracDelta(t), "inverse Laplace incorrect.")

        aw = a(j * omega)
        self.assertEqual2(aw.real, (omega**2 - 4) / (omega**2 + 4), "real part incorrect.")
        self.assertEqual2(aw.imag, -4 * omega / (omega**2 + 4), "imag part incorrect.")


    def test_sExpr2(self):
        """Lcapy: check sExpr2

        """
        a = (s + 2) * (s + 3) / (s - 2)
        self.assertEqual2(a.N, (s + 2) * (s + 3), "N incorrect.")
        self.assertEqual2(a.D, s - 2, "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), sorted([-3.0, -2.0]), "zeros incorrect.")

        self.assertEqual2(
            a.partfrac(), s + 7 + 20 / (s - 2), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), s + 7 + 20 / (s - 2), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), (s**2 + 5 * s + 6) / (s - 2), "general incorrect.")
        self.assertEqual2(
            a.canonical(), (s**2 + 5 * s + 6) / (s - 2), "canonical incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 20 * exp(2 * t) * H(t) + 7 * DiracDelta(t) + DiracDelta(t, 1), "inverse Laplace incorrect.")

    def test_sExpr3(self):
        """Lcapy: check sExpr3

        """
        a = (s**2 + 5 * s + 6) / (s - 2)
        self.assertEqual2(a.N, s ** 2 + 5 * s + 6, "N incorrect.")
        self.assertEqual2(a.D, s - 2, "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), sorted([-3, -2]), "zeros incorrect.")

        self.assertEqual2(
            a.partfrac(), s + 7 + 20 / (s - 2), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), s + 7 + 20 / (s - 2), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), (s**2 + 5 * s + 6) / (s - 2), "general incorrect.")
        self.assertEqual2(
            a.canonical(), (s**2 + 5 * s + 6) / (s - 2), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), (s + 2) * (s + 3) / (s - 2), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 20 * exp(2 * t) * H(t) + 7 * DiracDelta(t) + DiracDelta(t, 1), "inverse Laplace incorrect.")

    def test_sExpr4(self):
        """Lcapy: check sExpr4

        """
        a = 1 / ((s - j) * (s + j))
        self.assertEqual2(a.N, 1, "N incorrect.")
        self.assertEqual2(a.D, (s - j) * (s + j), "D incorrect.")

        self.assertEqual2(set(a.poles()), set([-j, j]), "poles incorrect.")
        self.assertEqual2(a.zeros(), {}, "zeros incorrect.")

        # This depends on if 2 * (s + j) is expanded to 2 * s + 2 * j
        # self.assertEqual2(
        # a.partfrac(), j / (2 * (s + j)) - j / (2 * (s - j)), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), 1 / (s**2 + 1), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), 1 / (s**2 + 1), "general incorrect.")
        self.assertEqual2(
            a.canonical(), 1 / (s**2 + 1), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), 1 / ((s - j) * (s + j)), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), sin(t) * H(t), "inverse Laplace incorrect.")

    def test_sExpr5(self):
        """Lcapy: check sExpr5

        """
        a = 1 / ((s - 1j) * (s + 1j))
        self.assertEqual2(a.N, 1, "N incorrect.")
        self.assertEqual2(a.D, (s - j) * (s + j), "D incorrect.")

        self.assertEqual2(set(a.poles()), set([-j, j]), "poles incorrect.")
        self.assertEqual2(len(a.zeros()), 0, "zeros incorrect.")

        # This depends on if 2 * (s + j) is expanded to 2 * s + 2 * j
        # self.assertEqual2(
        #    a.partfrac(), j / (2 * (s + j)) - j / (2 * (s - j)), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), 1 / (s**2 + 1), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), 1 / (s**2 + 1), "general incorrect.")
        self.assertEqual2(
            a.canonical(), 1 / (s**2 + 1), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), 1 / ((s - j) * (s + j)), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), sin(t) * H(t), "inverse Laplace incorrect.")

    def test_wExpr1(self):
        """Lcapy: check wExpr1

        """

        A = (j * omega + 3) / (j * omega - 4)
        self.assertEqual2(A.N, j * omega + 3, "N incorrect.")
        self.assertEqual2(A.D, j * omega - 4, "D incorrect.")
        self.assertEqual2(A.real, (omega**2 - 12) / (omega**2 + 16), "real incorrect.")
        self.assertEqual2(A.imag, -7 * omega / (omega**2 + 16), "imag incorrect.")

    def test_tExpr1(self):
        """Lcapy: check tExpr1

        """
        a = t**2

        self.assertEqual(a.evaluate(2), 4.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate((2, 3))[1], 9.0, "vector evaluate incorrect.")

    def test_step(self):
        """Lcapy: check step

        """
        a = u(t)

        self.assertEqual(a.evaluate(2), 1.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate((-2, 2))[1], 1.0, "vector evaluate incorrect.")
        self.assertEqual(a.evaluate((-2, 2))[0], 0.0, "vector evaluate incorrect.")
        self.assertEqual(a.laplace(), 1 / s, "Laplace transform incorrect.")

    def test_delta(self):
        """Lcapy: check delta

        """
        a = delta(t)

        self.assertEqual(a.evaluate(2), 0, "scalar evaluate incorrect.")
        self.assertEqual(a.laplace(), 1, "Laplace transform incorrect.")

    def test_jomega(self):
        """Lcapy: check jomega

        """

        a = sExpr('s+2')
        b = a(j * omega)

        self.assertEqual2(b, j * omega + 2, "Substitution failed.")
        self.assertEqual2(a.jomega, j * omega + 2, "jomega failed.")

    def test_subs1(self):
        """Lcapy: check subs

        """

        a = s.subs(omega)

        self.assertEqual(a.expr.is_real, True, "Lost is_real.")
        self.assertEqual2(a, omega, "Substitution fail.")

    def test_subs2(self):
        """Lcapy: check subs

        """

        a1 = s.subs(omega)
        a2 = s.subs(s, omega)

        self.assertEqual(a1, a2, "Substitution fail.")

        a3 = s.subs({s: omega})
        self.assertEqual(a1, a3, "Substitution fail with dict.")


    def test_types(self):
        """Lcapy: check types

        """

        c = cExpr(10)
        self.assertEqual(type(10 + c), cExpr, "Not cExpr")
        self.assertEqual(type(c + 10), cExpr, "Not cExpr")
        self.assertEqual(type(cExpr(10) + c), cExpr, "Not cExpr")
        self.assertEqual(type(c + cExpr(10)), cExpr, "Not cExpr")

        self.assertEqual(type(10 + s), sExpr, "Not sExpr")
        self.assertEqual(type(s + 10), sExpr, "Not sExpr")
        self.assertEqual(type(cExpr(10) + s), sExpr, "Not sExpr")
        self.assertEqual(type(s + cExpr(10)), sExpr, "Not sExpr")

        self.assertEqual(type(10 + t), tExpr, "Not tExpr")
        self.assertEqual(type(t + 10), tExpr, "Not tExpr")
        self.assertEqual(type(cExpr(10) + t), tExpr, "Not tExpr")
        self.assertEqual(type(t + cExpr(10)), tExpr, "Not tExpr")

        v = Vs(10)
        self.assertEqual(type(10 + v), Vs, "Not Vs")
        self.assertEqual(type(v + 10), Vs, "Not Vs")
        self.assertEqual(type(sExpr(10) + v), Vs, "Not Vs")
        self.assertEqual(type(v + sExpr(10)), Vs, "Not Vs")

        self.assertEqual(type(omega * t), tExpr, "Not tExpr")
        self.assertEqual(type(t * omega), tExpr, "Not tExpr")                

    def test_evaluate(self):
        """Lcapy: check evaluate

        """

        self.assertEqual(t.evaluate(10), 10.0, "Evaluate fail for scalar")
        self.assertEqual(t.evaluate((10, 20))[0], 10.0, "Evaluate fail for vector")
        self.assertEqual((t * 5 + 1).evaluate((10, 20))[0], 51.0, "Evaluate fail for vector")
        a = exp(t)
        self.assertEqual(a.evaluate(0j), 1, "Evaluate fail for exp(0j)")
        a = sqrt(t)
        self.assertEqual(a.evaluate(0j), 0j, "Evaluate fail for sqrt(0j)")
        self.assertEqual(a.evaluate(2j), 1 + 1j, "Evaluate fail for sqrt(1+1j)")
        self.assertEqual(a.evaluate(4), 2, "Evaluate fail for sqrt(4)")

    def test_zp2k(self):

        self.assertEqual(zp2tf([], [0, -1]), 1 / (s * (s + 1)), "zp2tf")

    def test_fourier(self):

        self.assertEqual((t * 0 + 1).fourier(), DiracDelta(f))
        self.assertEqual((t * 0 + 1).fourier().inverse_fourier(), 1)
        self.assertEqual(t.fourier(), 2 * j * pi * DiracDelta(f, 1))
        self.assertEqual(2 * cos(2 * pi * t).fourier(),
                         DiracDelta(f - 1) + DiracDelta(f + 1))
        self.assertEqual(2 * sin(2 * pi * t).fourier(),
                         -j * DiracDelta(f - 1) + j * DiracDelta(f + 1))
        self.assertEqual(exp(j * 2 * pi * t).fourier(), DiracDelta(f - 1))
        self.assertEqual(exp(j * 2 * pi * t).fourier().inverse_fourier(),
                         exp(j * 2 * pi * t))
        self.assertEqual(exp(-j * 2 * pi * t).fourier(), DiracDelta(f + 1))
        self.assertEqual(exp(-j * 2 * pi * t).fourier().inverse_fourier(),
                         exp(-j * 2 * pi * t))

    def test_inverse_fourier(self):

        self.assertEqual((1 / (s + 1))(j * omega).inverse_fourier(), exp(-t) * Heaviside(t))
        self.assertEqual((1 / (s + 1))(j * omega)(2 * pi * f).inverse_fourier(), exp(-t) * Heaviside(t))

    def test_rms(self):

        self.assertEqual(Vconst(2).rms(), Vt(2))
        self.assertEqual(Vphasor(2).rms(), Vt(1))

    def test_assumptions(self):
        """Lcapy: check assumptions

        """

        self.assertEqual(Heaviside(t).is_causal, True, "Heaviside(t).is_causal")
        self.assertEqual(Heaviside(t).is_dc, False, "Heaviside(t).is_dc")
        self.assertEqual(Heaviside(t).is_ac, False, "Heaviside(t).is_ac")
        self.assertEqual(DiracDelta(t).is_causal, True, "DiracDelta(t).is_causal")
        self.assertEqual(DiracDelta(t).is_dc, False, "DiracDelta(t).is_dc")
        self.assertEqual(DiracDelta(t).is_ac, False, "DiracDelta(t).is_ac")
        self.assertEqual(cos(t).is_causal, False, "cos(t).is_causal")
        self.assertEqual(cos(t).is_dc, False, "cos(t).is_dc")
        self.assertEqual(cos(t).is_ac, True, "cos(t).is_ac")

        self.assertEqual(Heaviside(t).laplace().is_causal, True,
                         "Heaviside(t).laplace().is_causal")
        self.assertEqual((Heaviside(t).laplace() +
                          DiracDelta(t).laplace()).is_causal, True)
        self.assertEqual((Heaviside(t).laplace() *
                          DiracDelta(t).laplace()).is_causal, True)
        self.assertEqual((Heaviside(t).laplace() *
                          cos(t).laplace()).is_causal, True)
        self.assertEqual(Heaviside(2 * t).is_causal, True, "Heaviside(2 * t).is_causal")
        self.assertEqual(Heaviside(t - 1).is_causal, True, "Heaviside(t - 1).is_causal")
        self.assertEqual(Heaviside(t + 1).is_causal, False, "Heaviside(t + 1).is_causal")
        self.assertEqual(Heaviside(2 * t - 1).is_causal, True, "Heaviside(2 * t - 1).is_causal")
        self.assertEqual(Heaviside(-2 * t - 1).is_causal, False, "Heaviside(-2 * t - 1).is_causal")
        
    def test_noise(self):
        a = Vn(2)
        self.assertEqual(a.nid, a.conjugate.nid, "Different nids for conjugate")
        self.assertEqual(a.nid, a.real.nid, "Different nids for real")
        self.assertEqual(a.nid, a.imag.nid, "Different nids for imag")
        
    def test_has(self):

        a = Expr('3 * exp(-t) * t * a')
        self.assertEqual(a.has(3), True, "has(3)")
        self.assertEqual(a.has(4), False, "has(4)")
        self.assertEqual(a.has(t), True, "has(t)")
        self.assertEqual(a.has_symbol(t), True, "has_symbol(t)")
        self.assertEqual(a.has_symbol('a'), True, "has_symbol(a)")
        self.assertEqual(a.has_symbol('b'), False, "has_symbol(b)")
        
    def test_expr(self):

        a = expr('3 * exp(-t) * t * a')
        self.assertEqual(isinstance(a, tExpr), True, "tExpr")        
        self.assertEqual(a.has(3), True, "has(3)")
        self.assertEqual(a.has(4), False, "has(4)")
        self.assertEqual(a.has(t), True, "has(t)")
        self.assertEqual(a.has_symbol(t), True, "has_symbol(t)")
        self.assertEqual(a.has_symbol('a'), True, "has_symbol(a)")
        self.assertEqual(a.has_symbol('b'), False, "has_symbol(b)")
        #self.assertEqual(a.symbols[1].is_positive, True, "a is positive")
        self.assertEqual(a.is_constant, False, "is_constant")                

        a = expr('3')
        self.assertEqual(a.is_constant, True, "3 is_constant")        

        self.assertEqual(isinstance(expr(t), tExpr), True, "tExpr")
        self.assertEqual(isinstance(expr(s), sExpr), True, "sExpr")
        self.assertEqual(isinstance(expr(f), fExpr), True, "fExpr")
        self.assertEqual(isinstance(expr(omega), omegaExpr), True, "omegaExpr")
        
        self.assertEqual(isinstance(symbol('c'), Expr), True, "symbol")


    def test_comparison(self):

        a = expr('3')
        b = expr('4')
        self.assertEqual(a < b, True, "a < b")
        self.assertEqual(a > b, False, "a > b")
        self.assertEqual(a <= b, True, "a <= b")
        self.assertEqual(a >= b, False, "a >= b")        
        self.assertEqual(a == b, False, "a == b")
        self.assertEqual(a != b, True, "a != b")        

    def test_rdiv(self):

        self.assertEqual(3 / expr('3'), 1, "3 / expr('3')")

    def test_div(self):

        self.assertEqual(expr('3') / 3, 1, "expr('3') / 3")        
        
    def test_rsub(self):

        self.assertEqual(3 - expr('3'), 0, "3 - expr('3')")

    def test_sub(self):

        self.assertEqual(expr('3') - 3, 0, "expr('3') - 3")

    def test_parallel(self):

        self.assertEqual(expr('4').parallel(expr('4')), 2, "parallel")

    def test_limit(self):

        self.assertEqual(expr('4').limit(t, 0), 4, "limit")
        self.assertEqual(expr('t + 4').limit(t, 0), 4, "limit")        
        
<commit_msg>Check repeated pole<commit_after>from lcapy import *
from lcapy.cexpr import cExpr
import unittest


class LcapyTester(unittest.TestCase):

    """Unit tests for lcapy

    """

    def assertEqual2(self, ans1, ans2, comment):

        try:
            self.assertEqual(ans1, ans2, comment)
        except AssertionError as e:
            pprint(ans1)
            pprint(ans2)
            raise AssertionError(e)

    def test_rmul(self):

        self.assertEqual2((j * omega).__class__,  omegaExpr, "j * omega fail.")

    def test_Expr1(self):
        """Lcapy: check Expr

        """
        a = Expr(3)
        self.assertEqual2(a.N, Expr(3), "N incorrect.")
        self.assertEqual2(a.D, Expr(1), "D incorrect.")
        self.assertEqual2(a.real, Expr(3), "real incorrect.")
        self.assertEqual2(a.imag, Expr(0), "imag incorrect.")
        self.assertEqual2(a.magnitude, Expr(3), "magnitude incorrect.")
        self.assertEqual2(a.phase, Expr(0), "phase incorrect.")
        self.assertEqual2(a.phase_degrees, Expr(0), "phase incorrect.")
        self.assertEqual2(a.sign, Expr(1), "sign incorrect.")
        self.assertEqual2(-a.sign, Expr(-1), "sign incorrect.")

        a = Expr(3j)
        self.assertEqual2(a.N, Expr(3j), "N incorrect.")
        self.assertEqual2(a.D, Expr(1), "D incorrect.")
        self.assertEqual2(a.real, Expr(0), "real incorrect.")
        self.assertEqual2(a.imag, Expr(3), "imag incorrect.")        
        self.assertEqual2(a.magnitude, Expr(3), "magnitude incorrect.")
        self.assertEqual2(abs(a), Expr(3), "abs incorrect.")        
        self.assertEqual2(a.phase, Expr(pi / 2), "phase incorrect.")
        self.assertEqual2(a.phase_degrees, Expr(90), "phase incorrect.")
        self.assertEqual2(a.sign, Expr(j), "sign incorrect.")
        self.assertEqual2(-a.sign, Expr(-j), "sign incorrect.")        

        
    def test_sExpr1(self):
        """Lcapy: check sExpr

        """
        a = sExpr('(s+2)/(s-2)')
        self.assertEqual2(a.N, sExpr('s+2'), "N incorrect.")
        self.assertEqual2(a.D, sExpr('s-2'), "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), [-2], "zeros incorrect.")

        self.assertEqual2(a.partfrac(), 1 + 4 / (s - 2), "partfrac incorrect.")

        self.assertEqual(a.evaluate(1), -3.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate(-2), 0.0, "scalar evaluate incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 4 * exp(2 * t) * H(t) + DiracDelta(t), "inverse Laplace incorrect.")

        aw = a(j * omega)
        self.assertEqual2(aw.real, (omega**2 - 4) / (omega**2 + 4), "real part incorrect.")
        self.assertEqual2(aw.imag, -4 * omega / (omega**2 + 4), "imag part incorrect.")


    def test_sExpr2(self):
        """Lcapy: check sExpr2

        """
        a = (s + 2) * (s + 3) / (s - 2)
        self.assertEqual2(a.N, (s + 2) * (s + 3), "N incorrect.")
        self.assertEqual2(a.D, s - 2, "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), sorted([-3.0, -2.0]), "zeros incorrect.")

        self.assertEqual2(
            a.partfrac(), s + 7 + 20 / (s - 2), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), s + 7 + 20 / (s - 2), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), (s**2 + 5 * s + 6) / (s - 2), "general incorrect.")
        self.assertEqual2(
            a.canonical(), (s**2 + 5 * s + 6) / (s - 2), "canonical incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 20 * exp(2 * t) * H(t) + 7 * DiracDelta(t) + DiracDelta(t, 1), "inverse Laplace incorrect.")

    def test_sExpr3(self):
        """Lcapy: check sExpr3

        """
        a = (s**2 + 5 * s + 6) / (s - 2)
        self.assertEqual2(a.N, s ** 2 + 5 * s + 6, "N incorrect.")
        self.assertEqual2(a.D, s - 2, "D incorrect.")

        self.assertEqual2(sorted(a.poles()), [2], "poles incorrect.")
        self.assertEqual2(sorted(a.zeros()), sorted([-3, -2]), "zeros incorrect.")

        self.assertEqual2(
            a.partfrac(), s + 7 + 20 / (s - 2), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), s + 7 + 20 / (s - 2), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), (s**2 + 5 * s + 6) / (s - 2), "general incorrect.")
        self.assertEqual2(
            a.canonical(), (s**2 + 5 * s + 6) / (s - 2), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), (s + 2) * (s + 3) / (s - 2), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), 20 * exp(2 * t) * H(t) + 7 * DiracDelta(t) + DiracDelta(t, 1), "inverse Laplace incorrect.")

    def test_sExpr4(self):
        """Lcapy: check sExpr4

        """
        a = 1 / ((s - j) * (s + j))
        self.assertEqual2(a.N, 1, "N incorrect.")
        self.assertEqual2(a.D, (s - j) * (s + j), "D incorrect.")

        self.assertEqual2(set(a.poles()), set([-j, j]), "poles incorrect.")
        self.assertEqual2(a.zeros(), {}, "zeros incorrect.")

        # This depends on if 2 * (s + j) is expanded to 2 * s + 2 * j
        # self.assertEqual2(
        # a.partfrac(), j / (2 * (s + j)) - j / (2 * (s - j)), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), 1 / (s**2 + 1), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), 1 / (s**2 + 1), "general incorrect.")
        self.assertEqual2(
            a.canonical(), 1 / (s**2 + 1), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), 1 / ((s - j) * (s + j)), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), sin(t) * H(t), "inverse Laplace incorrect.")

    def test_sExpr5(self):
        """Lcapy: check sExpr5

        """
        a = 1 / ((s - 1j) * (s + 1j))
        self.assertEqual2(a.N, 1, "N incorrect.")
        self.assertEqual2(a.D, (s - j) * (s + j), "D incorrect.")

        self.assertEqual2(set(a.poles()), set([-j, j]), "poles incorrect.")
        self.assertEqual2(len(a.zeros()), 0, "zeros incorrect.")

        # This depends on if 2 * (s + j) is expanded to 2 * s + 2 * j
        # self.assertEqual2(
        #    a.partfrac(), j / (2 * (s + j)) - j / (2 * (s - j)), "partfrac incorrect.")
        self.assertEqual2(
            a.mixedfrac(), 1 / (s**2 + 1), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), 1 / (s**2 + 1), "general incorrect.")
        self.assertEqual2(
            a.canonical(), 1 / (s**2 + 1), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), 1 / ((s - j) * (s + j)), "ZPK incorrect.")

        self.assertEqual(a.inverse_laplace(causal=True), sin(t) * H(t), "inverse Laplace incorrect.")


    def test_sExpr6(self):
        """Lcapy: check sExpr6 (repeated poles)

        """
        a = 1 / ((s + 4) * (s + 4))
        self.assertEqual2(a.N, 1, "N incorrect.")
        self.assertEqual2(a.D, (s + 4)**2, "D incorrect.")

        self.assertEqual2(a.poles(), {-4:2}, "poles incorrect.")
        self.assertEqual2(a.zeros(), {}, "zeros incorrect.")

        self.assertEqual2(
            a.mixedfrac(), 1 / (s**2 + 8 * s + 16), "mixedfrac incorrect.")
        self.assertEqual2(
            a.general(), 1 / (s**2 + 8 * s + 16), "general incorrect.")
        self.assertEqual2(
            a.canonical(), 1 / (s**2 + 8 * s + 16), "canonical incorrect.")
        self.assertEqual2(
            a.ZPK(), 1 / ((s + 4)**2), "ZPK incorrect.")
        self.assertEqual(a.inverse_laplace(causal=True), t * exp(-4 * t) * Heaviside(t), "inverse Laplace incorrect.")        

    def test_wExpr1(self):
        """Lcapy: check wExpr1

        """

        A = (j * omega + 3) / (j * omega - 4)
        self.assertEqual2(A.N, j * omega + 3, "N incorrect.")
        self.assertEqual2(A.D, j * omega - 4, "D incorrect.")
        self.assertEqual2(A.real, (omega**2 - 12) / (omega**2 + 16), "real incorrect.")
        self.assertEqual2(A.imag, -7 * omega / (omega**2 + 16), "imag incorrect.")

    def test_tExpr1(self):
        """Lcapy: check tExpr1

        """
        a = t**2

        self.assertEqual(a.evaluate(2), 4.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate((2, 3))[1], 9.0, "vector evaluate incorrect.")

    def test_step(self):
        """Lcapy: check step

        """
        a = u(t)

        self.assertEqual(a.evaluate(2), 1.0, "scalar evaluate incorrect.")
        self.assertEqual(a.evaluate((-2, 2))[1], 1.0, "vector evaluate incorrect.")
        self.assertEqual(a.evaluate((-2, 2))[0], 0.0, "vector evaluate incorrect.")
        self.assertEqual(a.laplace(), 1 / s, "Laplace transform incorrect.")

    def test_delta(self):
        """Lcapy: check delta

        """
        a = delta(t)

        self.assertEqual(a.evaluate(2), 0, "scalar evaluate incorrect.")
        self.assertEqual(a.laplace(), 1, "Laplace transform incorrect.")

    def test_jomega(self):
        """Lcapy: check jomega

        """

        a = sExpr('s+2')
        b = a(j * omega)

        self.assertEqual2(b, j * omega + 2, "Substitution failed.")
        self.assertEqual2(a.jomega, j * omega + 2, "jomega failed.")

    def test_subs1(self):
        """Lcapy: check subs

        """

        a = s.subs(omega)

        self.assertEqual(a.expr.is_real, True, "Lost is_real.")
        self.assertEqual2(a, omega, "Substitution fail.")

    def test_subs2(self):
        """Lcapy: check subs

        """

        a1 = s.subs(omega)
        a2 = s.subs(s, omega)

        self.assertEqual(a1, a2, "Substitution fail.")

        a3 = s.subs({s: omega})
        self.assertEqual(a1, a3, "Substitution fail with dict.")


    def test_types(self):
        """Lcapy: check types

        """

        c = cExpr(10)
        self.assertEqual(type(10 + c), cExpr, "Not cExpr")
        self.assertEqual(type(c + 10), cExpr, "Not cExpr")
        self.assertEqual(type(cExpr(10) + c), cExpr, "Not cExpr")
        self.assertEqual(type(c + cExpr(10)), cExpr, "Not cExpr")

        self.assertEqual(type(10 + s), sExpr, "Not sExpr")
        self.assertEqual(type(s + 10), sExpr, "Not sExpr")
        self.assertEqual(type(cExpr(10) + s), sExpr, "Not sExpr")
        self.assertEqual(type(s + cExpr(10)), sExpr, "Not sExpr")

        self.assertEqual(type(10 + t), tExpr, "Not tExpr")
        self.assertEqual(type(t + 10), tExpr, "Not tExpr")
        self.assertEqual(type(cExpr(10) + t), tExpr, "Not tExpr")
        self.assertEqual(type(t + cExpr(10)), tExpr, "Not tExpr")

        v = Vs(10)
        self.assertEqual(type(10 + v), Vs, "Not Vs")
        self.assertEqual(type(v + 10), Vs, "Not Vs")
        self.assertEqual(type(sExpr(10) + v), Vs, "Not Vs")
        self.assertEqual(type(v + sExpr(10)), Vs, "Not Vs")

        self.assertEqual(type(omega * t), tExpr, "Not tExpr")
        self.assertEqual(type(t * omega), tExpr, "Not tExpr")                

    def test_evaluate(self):
        """Lcapy: check evaluate

        """

        self.assertEqual(t.evaluate(10), 10.0, "Evaluate fail for scalar")
        self.assertEqual(t.evaluate((10, 20))[0], 10.0, "Evaluate fail for vector")
        self.assertEqual((t * 5 + 1).evaluate((10, 20))[0], 51.0, "Evaluate fail for vector")
        a = exp(t)
        self.assertEqual(a.evaluate(0j), 1, "Evaluate fail for exp(0j)")
        a = sqrt(t)
        self.assertEqual(a.evaluate(0j), 0j, "Evaluate fail for sqrt(0j)")
        self.assertEqual(a.evaluate(2j), 1 + 1j, "Evaluate fail for sqrt(1+1j)")
        self.assertEqual(a.evaluate(4), 2, "Evaluate fail for sqrt(4)")

    def test_zp2k(self):

        self.assertEqual(zp2tf([], [0, -1]), 1 / (s * (s + 1)), "zp2tf")

    def test_fourier(self):

        self.assertEqual((t * 0 + 1).fourier(), DiracDelta(f))
        self.assertEqual((t * 0 + 1).fourier().inverse_fourier(), 1)
        self.assertEqual(t.fourier(), 2 * j * pi * DiracDelta(f, 1))
        self.assertEqual(2 * cos(2 * pi * t).fourier(),
                         DiracDelta(f - 1) + DiracDelta(f + 1))
        self.assertEqual(2 * sin(2 * pi * t).fourier(),
                         -j * DiracDelta(f - 1) + j * DiracDelta(f + 1))
        self.assertEqual(exp(j * 2 * pi * t).fourier(), DiracDelta(f - 1))
        self.assertEqual(exp(j * 2 * pi * t).fourier().inverse_fourier(),
                         exp(j * 2 * pi * t))
        self.assertEqual(exp(-j * 2 * pi * t).fourier(), DiracDelta(f + 1))
        self.assertEqual(exp(-j * 2 * pi * t).fourier().inverse_fourier(),
                         exp(-j * 2 * pi * t))

    def test_inverse_fourier(self):

        self.assertEqual((1 / (s + 1))(j * omega).inverse_fourier(), exp(-t) * Heaviside(t))
        self.assertEqual((1 / (s + 1))(j * omega)(2 * pi * f).inverse_fourier(), exp(-t) * Heaviside(t))

    def test_rms(self):

        self.assertEqual(Vconst(2).rms(), Vt(2))
        self.assertEqual(Vphasor(2).rms(), Vt(1))

    def test_assumptions(self):
        """Lcapy: check assumptions

        """

        self.assertEqual(Heaviside(t).is_causal, True, "Heaviside(t).is_causal")
        self.assertEqual(Heaviside(t).is_dc, False, "Heaviside(t).is_dc")
        self.assertEqual(Heaviside(t).is_ac, False, "Heaviside(t).is_ac")
        self.assertEqual(DiracDelta(t).is_causal, True, "DiracDelta(t).is_causal")
        self.assertEqual(DiracDelta(t).is_dc, False, "DiracDelta(t).is_dc")
        self.assertEqual(DiracDelta(t).is_ac, False, "DiracDelta(t).is_ac")
        self.assertEqual(cos(t).is_causal, False, "cos(t).is_causal")
        self.assertEqual(cos(t).is_dc, False, "cos(t).is_dc")
        self.assertEqual(cos(t).is_ac, True, "cos(t).is_ac")

        self.assertEqual(Heaviside(t).laplace().is_causal, True,
                         "Heaviside(t).laplace().is_causal")
        self.assertEqual((Heaviside(t).laplace() +
                          DiracDelta(t).laplace()).is_causal, True)
        self.assertEqual((Heaviside(t).laplace() *
                          DiracDelta(t).laplace()).is_causal, True)
        self.assertEqual((Heaviside(t).laplace() *
                          cos(t).laplace()).is_causal, True)
        self.assertEqual(Heaviside(2 * t).is_causal, True, "Heaviside(2 * t).is_causal")
        self.assertEqual(Heaviside(t - 1).is_causal, True, "Heaviside(t - 1).is_causal")
        self.assertEqual(Heaviside(t + 1).is_causal, False, "Heaviside(t + 1).is_causal")
        self.assertEqual(Heaviside(2 * t - 1).is_causal, True, "Heaviside(2 * t - 1).is_causal")
        self.assertEqual(Heaviside(-2 * t - 1).is_causal, False, "Heaviside(-2 * t - 1).is_causal")
        
    def test_noise(self):
        a = Vn(2)
        self.assertEqual(a.nid, a.conjugate.nid, "Different nids for conjugate")
        self.assertEqual(a.nid, a.real.nid, "Different nids for real")
        self.assertEqual(a.nid, a.imag.nid, "Different nids for imag")
        
    def test_has(self):

        a = Expr('3 * exp(-t) * t * a')
        self.assertEqual(a.has(3), True, "has(3)")
        self.assertEqual(a.has(4), False, "has(4)")
        self.assertEqual(a.has(t), True, "has(t)")
        self.assertEqual(a.has_symbol(t), True, "has_symbol(t)")
        self.assertEqual(a.has_symbol('a'), True, "has_symbol(a)")
        self.assertEqual(a.has_symbol('b'), False, "has_symbol(b)")
        
    def test_expr(self):

        a = expr('3 * exp(-t) * t * a')
        self.assertEqual(isinstance(a, tExpr), True, "tExpr")        
        self.assertEqual(a.has(3), True, "has(3)")
        self.assertEqual(a.has(4), False, "has(4)")
        self.assertEqual(a.has(t), True, "has(t)")
        self.assertEqual(a.has_symbol(t), True, "has_symbol(t)")
        self.assertEqual(a.has_symbol('a'), True, "has_symbol(a)")
        self.assertEqual(a.has_symbol('b'), False, "has_symbol(b)")
        #self.assertEqual(a.symbols[1].is_positive, True, "a is positive")
        self.assertEqual(a.is_constant, False, "is_constant")                

        a = expr('3')
        self.assertEqual(a.is_constant, True, "3 is_constant")        

        self.assertEqual(isinstance(expr(t), tExpr), True, "tExpr")
        self.assertEqual(isinstance(expr(s), sExpr), True, "sExpr")
        self.assertEqual(isinstance(expr(f), fExpr), True, "fExpr")
        self.assertEqual(isinstance(expr(omega), omegaExpr), True, "omegaExpr")
        
        self.assertEqual(isinstance(symbol('c'), Expr), True, "symbol")


    def test_comparison(self):

        a = expr('3')
        b = expr('4')
        self.assertEqual(a < b, True, "a < b")
        self.assertEqual(a > b, False, "a > b")
        self.assertEqual(a <= b, True, "a <= b")
        self.assertEqual(a >= b, False, "a >= b")        
        self.assertEqual(a == b, False, "a == b")
        self.assertEqual(a != b, True, "a != b")        

    def test_rdiv(self):

        self.assertEqual(3 / expr('3'), 1, "3 / expr('3')")

    def test_div(self):

        self.assertEqual(expr('3') / 3, 1, "expr('3') / 3")        
        
    def test_rsub(self):

        self.assertEqual(3 - expr('3'), 0, "3 - expr('3')")

    def test_sub(self):

        self.assertEqual(expr('3') - 3, 0, "expr('3') - 3")

    def test_parallel(self):

        self.assertEqual(expr('4').parallel(expr('4')), 2, "parallel")

    def test_limit(self):

        self.assertEqual(expr('4').limit(t, 0), 4, "limit")
        self.assertEqual(expr('t + 4').limit(t, 0), 4, "limit")        
        

{'fraction_non_alphanumeric': 0.18090980804627926, 'fraction_numerical': 0.02801881555497122, 'mean_word_length': 2.3315164492894684, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5361728', 'n_tokens_mistral': 12520, 'n_tokens_neox': 11551, 'n_words': 2535}