aboutsummaryrefslogtreecommitdiff
path: root/tests/test_vector.cpp
blob: a776dc8ebea79bbb716a709556512c9dcea3e786 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import linalgebra;

#include <catch2/catch_approx.hpp>
#include <catch2/catch_test_macros.hpp>

#include <type_traits>
#include <utility>

using linalgebra::DimensionMismatchError;
using linalgebra::Vector;

TEST_CASE("Vector constructors initialize size and values", "[vector]") {
    const Vector empty;
    REQUIRE(empty.size() == 0);
    REQUIRE(empty.empty());

    const Vector zeroed(4);
    REQUIRE(zeroed.size() == 4);
    for (std::size_t i = 0; i < zeroed.size(); ++i) {
        CHECK(zeroed[i] == 0.0);
    }

    const Vector filled(3, 2.5);
    REQUIRE(filled.size() == 3);
    CHECK(filled[0] == 2.5);
    CHECK(filled[1] == 2.5);
    CHECK(filled[2] == 2.5);
}

TEST_CASE("Vector supports checked element access and fill", "[vector]") {
    Vector v{1.0, 2.0, 3.0};
    REQUIRE(v.size() == 3);

    v[1] = 7.0;
    CHECK(v[0] == 1.0);
    CHECK(v[1] == 7.0);
    CHECK(v[2] == 3.0);

    v.fill(-2.0);
    CHECK(v[0] == -2.0);
    CHECK(v[1] == -2.0);
    CHECK(v[2] == -2.0);

    CHECK_THROWS_AS(v[3], std::out_of_range);
}

TEST_CASE("Vector copy and move preserve values", "[vector]") {
    static_assert(std::is_nothrow_move_constructible_v<Vector>);

    Vector original{4.0, -1.0, 8.0};
    Vector copied = original;
    copied[0] = 10.0;

    CHECK(original[0] == 4.0);
    CHECK(copied[0] == 10.0);

    Vector moved = std::move(original);
    REQUIRE(moved.size() == 3);
    CHECK(moved[0] == 4.0);
    CHECK(moved[1] == -1.0);
    CHECK(moved[2] == 8.0);
}

TEST_CASE("Vector arithmetic enforces shape compatibility", "[vector]") {
    const Vector a{1.0, 2.0, 3.0};
    const Vector b{4.0, 5.0, 6.0};

    const Vector sum = a + b;
    CHECK(sum[0] == 5.0);
    CHECK(sum[1] == 7.0);
    CHECK(sum[2] == 9.0);

    const Vector diff = b - a;
    CHECK(diff[0] == 3.0);
    CHECK(diff[1] == 3.0);
    CHECK(diff[2] == 3.0);

    const Vector scaled = 0.5 * a;
    CHECK(scaled[0] == 0.5);
    CHECK(scaled[1] == 1.0);
    CHECK(scaled[2] == 1.5);

    CHECK(linalgebra::dot(a, b) == 32.0);

    const Vector short_vec{1.0, 2.0};
    CHECK_THROWS_AS(a + short_vec, DimensionMismatchError);
    CHECK_THROWS_AS(linalgebra::dot(a, short_vec), DimensionMismatchError);
}

TEST_CASE("Vector 2-norm matches manually computed values", "[vector][norms]") {
    const Vector v{3.0, 4.0};
    CHECK(linalgebra::norm2(v) == Catch::Approx(5.0));

    const Vector zero(5);
    CHECK(linalgebra::norm2(zero) == Catch::Approx(0.0));
}