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 97 98 99 100 101 102 103 104 105 106 107 108 109
|
#include <gtest/gtest.h>
#include "fuzzy/Discrete_Double_Fuzzy.h"
using namespace aevol;
class Discrete_Double_Fuzzy_Exposed : public Discrete_Double_Fuzzy {
public:
Discrete_Double_Fuzzy_Exposed(size_t vector_size): Discrete_Double_Fuzzy(vector_size) {}
auto& length() { return nb_intervals_; };
auto& d_length() { return nb_intervals_d_; };
auto& points() { return points_; };
};
TEST(DiscreteDoubleFuzzyTest, Flat) {
auto small_flat_0 = Discrete_Double_Fuzzy_Exposed(2); // 2 points => {0, 1}
auto small_flat_1 = Discrete_Double_Fuzzy_Exposed(2); // 2 points => {0, 1}
const auto large_size = size_t{300};
auto large_flat_p5 = Discrete_Double_Fuzzy_Exposed(large_size);
EXPECT_EQ(small_flat_0.get_geometric_area(), 0);
EXPECT_EQ(small_flat_1.get_geometric_area(), 0);
EXPECT_EQ(large_flat_p5.get_geometric_area(), 0);
small_flat_0.add_point(0, 0);
small_flat_0.add_point(1, 0);
EXPECT_EQ(small_flat_0.points()[0], 0);
EXPECT_EQ(small_flat_0.points()[1], 0);
EXPECT_EQ(small_flat_0.get_geometric_area(), 0);
small_flat_1.add_point(0, 1);
small_flat_1.add_point(1, 1);
EXPECT_EQ(small_flat_1.points()[0], 1);
EXPECT_EQ(small_flat_1.points()[1], 1);
EXPECT_EQ(small_flat_1.get_geometric_area(), 1);
for (auto i = size_t{0}; i < large_size; ++i) {
large_flat_p5.add_point(i / (static_cast<double>(large_size) - 1), .5);
}
EXPECT_FLOAT_EQ(large_flat_p5.points()[0], .5);
EXPECT_FLOAT_EQ(large_flat_p5.points()[150], .5);
EXPECT_FLOAT_EQ(large_flat_p5.points()[299], .5);
EXPECT_FLOAT_EQ(large_flat_p5.get_geometric_area(), .5);
}
TEST(DiscreteDoubleFuzzyTest, AddPoint) {
const auto size = size_t{5}; // 5 points => {0, .25, .5, .75, 1}
auto fuzzy = Discrete_Double_Fuzzy_Exposed(size);
// Add point with ~exact match for x
auto h1 = .1;
fuzzy.add_point(.5, h1);
EXPECT_EQ(fuzzy.points()[2], h1);
// Add point without exact match for x
fuzzy.add_point(.1, h1); // x between indices 0 and 1 (closest to 0)
EXPECT_EQ(fuzzy.points()[0], h1);
EXPECT_EQ(fuzzy.points()[1], 0);
auto h2 = .5;
fuzzy.add_point(.2, h2); // x between indices 0 and 1 (closest to 1)
EXPECT_EQ(fuzzy.points()[0], h1);
EXPECT_EQ(fuzzy.points()[1], h2);
auto halfway = .875;
EXPECT_EQ(1 - halfway, halfway - .75);
fuzzy.add_point(halfway, .5); // x between indices 3 and 4 (halfway)
// NB: std::round rounds halfway cases away from zero
EXPECT_EQ(fuzzy.points()[3], 0);
EXPECT_EQ(fuzzy.points()[4], .5);
}
TEST(DiscreteDoubleFuzzyTest, AddTriangle) {
const auto size = size_t{5}; // 5 points => {0, .25, .5, .75, 1}
// Add triangle with only ~exact matches for x
auto fuzzy = Discrete_Double_Fuzzy_Exposed(size);
auto m = .5;
auto w = .25;
auto h = .1;
fuzzy.add_triangle(m, w, h);
EXPECT_EQ(fuzzy.points()[0], 0);
EXPECT_EQ(fuzzy.points()[1], 0);
EXPECT_EQ(fuzzy.points()[2], h);
EXPECT_EQ(fuzzy.points()[3], 0);
EXPECT_EQ(fuzzy.points()[4], 0);
// Add triangle with only m as an exact match for x
auto fuzzy2 = Discrete_Double_Fuzzy_Exposed(size);
m = .5;
w = .3; // spans indices 1 through 3
h = .1;
fuzzy2.add_triangle(m, w, h);
EXPECT_EQ(fuzzy2.points()[0], 0);
EXPECT_FLOAT_EQ(fuzzy2.points()[1], h / w * (.25 - (m - w)));
EXPECT_EQ(fuzzy2.points()[2], h);
EXPECT_FLOAT_EQ(fuzzy2.points()[3], h / w * ((m + w) - .75));
EXPECT_EQ(fuzzy2.points()[4], 0);
// Add triangle with no matches for x
auto fuzzy3 = Discrete_Double_Fuzzy_Exposed(size);
m = .6;
w = .3; // spans indices 2 and 3
h = .25;
fuzzy3.add_triangle(m, w, h);
EXPECT_EQ(fuzzy3.points()[0], 0);
EXPECT_EQ(fuzzy3.points()[1], 0);
EXPECT_FLOAT_EQ(fuzzy3.points()[2], h / w * (.5 - (m - w)));
EXPECT_FLOAT_EQ(fuzzy3.points()[3], h / w * ((m + w) - .75));
EXPECT_EQ(fuzzy3.points()[4], 0);
}
|