def test_add():
    """Tests all overloads of the addition operator and add function.

    We'll test all binary operator overloads of the add function here to fully
    test the autocoder's binary operator generation function. These overloads
    will then be skipped for other operators.
    """
    a = lin.Matrix2x2([
        0.0, 1.0,
        2.0, 3.0
    ])
    b = lin.Matrix2x2()

    c = a + b
    assert type(c) is lin.Matrix2x2
    assert (c[0, 0] == 0.0) and (c[0, 1] == 1.0) and (c[1, 0] == 2.0) and \
            (c[1, 1] == 3.0)

    c = a + 2.0
    assert type(c) is lin.Matrix2x2
    assert (c[0, 0] == 2.0) and (c[0, 1] == 3.0) and (c[1, 0] == 4.0) and \
            (c[1, 1] == 5.0)

    c = 1.0 + a
    assert type(c) is lin.Matrix2x2
    assert (c[0, 0] == 1.0) and (c[0, 1] == 2.0) and (c[1, 0] == 3.0) and \
            (c[1, 1] == 4.0)

    b += 2.0
    assert type(b) is lin.Matrix2x2
    assert (b[0, 0] == 2.0) and (b[0, 1] == 2.0) and (b[1, 0] == 2.0) and \
            (b[1, 1] == 2.0)

    a += b
    assert type(a) is lin.Matrix2x2
    assert (a[0, 0] == 2.0) and (a[0, 1] == 3.0) and (a[1, 0] == 4.0) and \
            (a[1, 1] == 5.0)

    # Do a full binary operator test for add.
    a = lin.Vector2()
    b = lin.Vector2([1.0, 2.0])

    c = lin.add(a, b)
    assert type(c) is lin.Vector2
    assert (c[0] == 1.0) and (c[1] == 2.0)

    a = lin.add(c, -1.0)
    assert type(a) is lin.Vector2
    assert (a[0] == 0.0) and (a[1] == 1.0)

    b = lin.add(5.0, a)
    assert type(b) is lin.Vector2
    assert (b[0] == 5.0) and (b[1] == 6.0)
def test_positive():
    """Tests the unary plus operator.
    """
    u = lin.Vector2([1.0, -2.0])

    v = +u
    assert type(v) is lin.Vector2
    assert (v[0] == 1.0) and (v[1] == -2.0)
def test_norm():
    """Tests all the overloads of the vector two norm function.
    """
    u = lin.Vector2([3.0, 4.0])
    v = lin.RowVector3([3.0, 0.0, 4.0])

    assert lin.norm(u) == 5.0
    assert lin.norm(v) == 5.0
def test_isfinite():
    """Tests the isfinite function.
    """
    u = lin.Vector3([0.0, 0.0, float('nan')])
    v = lin.Vector2()

    assert not lin.isfinite(u)
    assert lin.isfinite(v)
def test_multiply():
    """Tests all the overloads of the multiplication operator and multiply
    function.
    """
    a = lin.Matrix3x3([
        1.0, 0.0, 0.0,
        0.0, 1.0, 0.0,
        0.0, 0.0, 1.0
    ])

    b = lin.Vector3([1.0, 2.0, 3.0])
    c = a * b
    assert type(c) is lin.Vector3
    assert (c[0] == 1.0) and (c[1] == 2.0) and (c[2] == 3.0)

    b = lin.Matrix3x2([
        1.0, 2.0,
        3.0, 4.0,
        5.0, 6.0
    ])
    c = a * b
    assert type(c) is lin.Matrix3x2
    for i in range(len(c)):
        assert c[i] == b[i]

    c = a * a
    assert type(c) is lin.Matrix3x3
    for i in range(len(c)):
        assert c[i] == a[i]

    a = lin.Vector2([1.0, 3.0])
    b = lin.RowVector2([1.0, 2.0])

    c = a * b
    assert type(c) is lin.Matrix2x2
    assert (c[0, 0] == 1.0) and (c[0, 1] == 2.0) and (c[1, 0] == 3.0) and \
            (c[1, 1] == 6.0)

    a *= 2.0
    assert (a[0] == 2.0) and (a[1] == 6.0)

    c = a * 0.5
    assert type(c) is lin.Vector2
    assert (c[0] == 1.0) and (c[1] == 3.0)

    c = 2.0 * b
    assert type(c) is lin.RowVector2
    assert (c[0] == 2.0) and (c[1] == 4.0)

    a = lin.RowVector2([2.0, 2.0])

    c = lin.multiply(a, b)
    assert type(c) is lin.RowVector2
    assert (c[0] == 2.0) and (c[1] == 4.0)
def test_negate():
    """Tests the unary negative operator and negate function.
    """
    u = lin.Vector2([1.0, -2.0])

    v = -u
    assert type(v) is lin.Vector2
    assert (v[0] == -1.0) and (v[1] == 2.0)

    u = lin.negate(v)
    assert type(u) is lin.Vector2
    assert (u[0] == 1.0) and (u[1] == -2.0)
def test_divide():
    """Tests all overloads of the division operator and divide function.
    """
    a = lin.Vector2([ 1.0, 2.0])
    b = lin.Vector2([-1.0, 4.0])

    c = a / b
    assert type(c) is lin.Vector2
    assert (c[0] == -1.0) and (c[1] == 0.5)

    c = a / 2.0
    assert type(c) is lin.Vector2
    assert (c[0] == 0.5) and (c[1] == 1.0)

    c = 2.0 / a
    assert type(c) is lin.Vector2
    assert (c[0] == 2.0) and (c[1] == 1.0)

    c = lin.divide(a, 2.0)
    assert type(c) is lin.Vector2
    assert (c[0] == 0.5) and (c[1] == 1.0)
def to_lin_vector(var):
    import lin
    if type(var) == list:
        _len = len(var)
        if _len == 2:
            var = lin.Vector2(var)
        elif _len == 3:
            var = lin.Vector3(var)
        elif _len == 4:
            var = lin.Vector4(var)
        else:
            raise RuntimeError(
                "Unexpected List Length, can't change into lin Vector")
    else:
        raise RuntimeError("Expected list, can't change into lin Vector")
    return var
def test_transpose():
    """Tests the transpose function and ensures the proper type is returned.
    """
    m = lin.Matrix2x3([
        0.0, 1.0, 2.0,
        3.0, 4.0, 5.0
    ])

    n = lin.transpose(m)
    assert type(n) is lin.Matrix3x2
    assert (n[0, 0] == 0.0) and (n[1, 0] == 1.0) and (n[2, 0] == 2.0) and \
        (n[0, 1] == 3.0) and (n[1, 1] == 4.0) and (n[2, 1] == 5.0)
    
    u = lin.Vector2([0.0, 1.0])

    v = lin.transpose(u)
    assert type(v) is lin.RowVector2
    assert (v[0] == 0.0) and (v[1] == 1.0)
def test_numpy_compatability():
    """Tests compatbility with NumPy and Python's buffer protocol system.

    Here, we're checking for the following functionality:
     * Constructs NumPy arrays from lin objects.
     * Construct lin objects from NumPy arrays.
     * Casting lin objects to NumPy arrays without copying.
    """
    m = np.array([
        [0.0, 1.0, 2.0, 3.0],
        [4.0, 5.0, 6.0, 7.0]
    ])

    n = lin.Matrix2x4(m)
    assert np.all(np.array(n) == m)

    m = lin.Vector2([0.0, 1.0])
    n = np.array(m, copy=False)
    
    n[0] = 3.0
    assert np.all(np.array(m) == n)