BICO  1.1
 All Classes Namespaces Files Functions Variables Typedefs Pages
point.cpp
Go to the documentation of this file.
1 #include "../point/point.h"
2 
3 #include "../exception/invalidargumentexception.h"
4 #include "../exception/invalidruntimeconfigurationexception.h"
5 
6 #include <math.h>
7 #include <iostream>
8 #include <numeric>
9 #include <vector>
10 #include <algorithm>
11 
12 using namespace CluE;
13 
14 Point::Point(std::vector<Point*> const& v)
15 {
16  size_t size = v.size();
17  double weightSum = 0;
18  if(size>0)
19  {
20  size_t dimension = v[0]->dimension();
21  weightSum = v[0]->weight;
22  for(size_t i=1; i < size; ++i)
23  {
24  weightSum+=v[i]->weight;
25  if(v[i]->dimension()!=dimension)
26  throw InvalidArgumentException(0, "Can't consolidate points with different dimensions!", "v");
27  }
28 
29  for(size_t n=0; n < dimension; ++n)
30  {
31  double c = 0;
32  for(size_t i=0; i < size; ++i)
33  {
34  c += v[i]->weight*(*v[i])[n];
35  }
36  c/=weightSum;
37  this->coordinates.push_back(c);
38  }
39 
40  this->weight = weightSum;
41  }
42  else
43  {
44  this->weight = 0;
45  }
46 }
47 
49 {
50  size_t d = this->dimension();
51 
52  if(x.dimension() != d)
53  throw InvalidArgumentException(0, "Incompatible dimensions!", "x");
54 
55  for(size_t i = 0; i < d; ++i)
56  (*this)[i] += x[i];
57 
58  return *this;
59 }
60 
62 {
63  size_t d = this->dimension();
64 
65  if(x.dimension() != d)
66  throw InvalidArgumentException(0, "Incompatible dimensions!", "x");
67 
68  for(size_t i = 0; i < d; ++i)
69  (*this)[i] -= x[i];
70 
71  return *this;
72 }
73 
74 Point Point::operator+(Point const & x) const
75 {
76  return Point(*this) += x;
77 }
78 
79 Point Point::operator-(Point const & x) const
80 {
81  return Point(*this) -= x;
82 }
83 
84 double Point::l1distance(Point const& p) const
85 {
86  size_t d = this->dimension();
87  if(p.dimension() != d)
88  throw InvalidArgumentException(0, "Incompatible dimensions!", "p");
89 
90  double sum = 0;
91  for(size_t i=0; i<d; ++i)
92  sum += fabs(p[i]-(*this)[i]);
93 
94  return sum;
95 }
96 
97 double Point::squaredL1distance(Point const& p) const
98 {
99  double l1 = this->l1distance(p);
100  return l1*l1;
101 }
102 
103 double Point::squaredL2distance(Point const& p) const
104 {
105  size_t d = this->dimension();
106  if(p.dimension() != d)
107  throw InvalidArgumentException(0, "Incompatible dimensions!", "p");
108 
109  double sum = 0;
110  for(unsigned int i=0; i<d; ++i)
111  {
112  double delta = p[i]-(*this)[i];
113  sum += delta*delta;
114  }
115 
116  return sum;
117 }
118 
119 double Point::l2distance(Point const& p) const
120 {
121  return sqrt(this->squaredL2distance(p));
122 }
123 
124 double Point::lpdistance(Point const& p, double exp) const
125 {
126  size_t d = this->dimension();
127  if(p.dimension() != d)
128  throw InvalidArgumentException(0, "Incompatible dimensions!", "p");
129 
130  double sum = 0;
131  for(size_t i=0; i<d; ++i)
132  {
133  double delta = p[i]-(*this)[i];
134  sum += pow(delta, exp);
135  }
136 
137  sum = pow(sum, 1/exp);
138 
139  return sum;
140 }
141 
142 double Point::squaredLpDistance(Point const& p, double exp) const
143 {
144  return pow(lpdistance(p, exp), 2);
145 }
146 
147 double Point::kullbackleibler(Point const& p) const
148 {
149  size_t d = this->dimension();
150  if(p.dimension() != d)
151  throw InvalidArgumentException(0, "Incompatible dimensions!", "p");
152 
153  std::vector<double> temp;
154  std::vector<double> sortedX;
155  std::vector<double> sortedY;
156  for(size_t i=0; i<d; ++i)
157  {
158  double xi = (*this)[i];
159  sortedX.push_back(xi);
160  double yi = p[i];
161  sortedY.push_back(yi);
162  if(xi>.0)
163  {
164  if(yi>.0)
165  {
166  double r = xi/yi;
167  if(r>.0)
168  temp.push_back(xi*log(r));
169  }
170  else
171  throw InvalidRuntimeConfigurationException(1, "Point has coordinate <= 0.");
172  }
173  else
174  throw InvalidRuntimeConfigurationException(1, "Point has coordinate <= 0.");
175  }
176 
177  // for numeric stability
178  sort(temp.begin(), temp.end());
179  sort(sortedX.begin(), sortedX.end());
180  sort(sortedY.begin(), sortedY.end());
181 
182  return accumulate(temp.begin(), temp.end(), .0)
183  -accumulate(sortedX.begin(), sortedX.end(), .0)
184  +accumulate(sortedY.begin(), sortedY.end(), .0);
185 }
186 
187 std::ostream& CluE::operator<<(std::ostream& os, Point const& p)
188 {
189  size_t d = p.dimension();
190  os << "(";
191  for(unsigned int i=0; i<d; i++)
192  {
193  os << p[i];
194  if(i < d-1)
195  os << ", ";
196  }
197  os << ")";
198  return os;
199 }
200 
201 Point CluE::operator*(double scalar, Point const & vec)
202 {
203  size_t d = vec.dimension();
204 
205  Point ret(vec);
206  for(size_t i = 0; i < d; ++i)
207  ret[i] = scalar * vec[i];
208 
209  return ret;
210 }
211 
212 double CluE::operator*(Point const & vec1, Point const & vec2)
213 {
214  size_t d = vec1.dimension();
215 
216  if(vec2.dimension() != d)
217  throw InvalidArgumentException(0, "Incompatible dimensions!", "vec1 / vec2");
218 
219  double ret = 0;
220  for(size_t i = 0; i<d; ++i)
221  ret += vec1[i] * vec2[i];
222 
223  return ret;
224 }
double l2distance(Point const &) const
Definition: point.cpp:119
size_t dimension() const
Definition: point.h:87
Point & operator+=(Point const &x)
Definition: point.cpp:48
Point & operator-=(Point const &x)
Definition: point.cpp:61
double squaredLpDistance(Point const &, double p) const
Definition: point.cpp:142
double weight
Definition: point.h:140
std::vector< double > coordinates
Definition: point.h:139
double squaredL2distance(Point const &) const
Definition: point.cpp:103
double lpdistance(Point const &, double p) const
Definition: point.cpp:124
Point(size_t dimension=0, double pointWeight=1.0)
Constructs a weighted point.
Definition: point.h:23
double kullbackleibler(Point const &) const
Definition: point.cpp:147
Point operator+(Point const &x) const
Definition: point.cpp:74
double squaredL1distance(Point const &) const
Definition: point.cpp:97
Point operator*(double scalar, Point const &vec)
Definition: point.cpp:201
Weighted point of arbitrary dimension.
Definition: point.h:17
Indicates invalid values of arguments.
Point operator-(Point const &x) const
Definition: point.cpp:79
Indicates that a computation entered an invalid configuration state.
double l1distance(Point const &) const
Definition: point.cpp:84
std::ostream & operator<<(std::ostream &, Point const &)
Definition: point.cpp:187