File: DiscreteDoubleFuzzyTest.cpp

package info (click to toggle)
aevol 9.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,176 kB
  • sloc: cpp: 26,650; ansic: 1,237; sh: 582; python: 545; makefile: 31
file content (109 lines) | stat: -rw-r--r-- 3,804 bytes parent folder | download
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);
}