Vector.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
20 #include <gtsam/base/Vector.h>
21 #include <stdexcept>
22 #include <cstdarg>
23 #include <limits>
24 #include <iostream>
25 #include <fstream>
26 #include <sstream>
27 #include <cassert>
28 #include <iomanip>
29 #include <cmath>
30 #include <cstdio>
31 #include <vector>
32 
33 using namespace std;
34 
35 namespace gtsam {
36 
37 /* *************************************************************************
38  * References:
39  * 1. https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
40  * 2. https://floating-point-gui.de/errors/comparison/
41  * ************************************************************************* */
42 bool fpEqual(double a, double b, double tol, bool check_relative_also) {
43  using std::abs;
44  using std::isnan;
45  using std::isinf;
46 
47  double DOUBLE_MIN_NORMAL = numeric_limits<double>::min() + 1.0;
48  double larger = (abs(b) > abs(a)) ? abs(b) : abs(a);
49 
50  // handle NaNs
51  if(isnan(a) || isnan(b)) {
52  return isnan(a) && isnan(b);
53  }
54  // handle inf
55  else if(isinf(a) || isinf(b)) {
56  return isinf(a) && isinf(b);
57  }
58  // If the two values are zero or both are extremely close to it
59  // relative error is less meaningful here
60  else if(a == 0 || b == 0 || (abs(a) + abs(b)) < DOUBLE_MIN_NORMAL) {
61  return abs(a-b) <= tol * DOUBLE_MIN_NORMAL;
62  }
63  // Check if the numbers are really close.
64  // Needed when comparing numbers near zero or tol is in vicinity.
65  else if (abs(a - b) <= tol) {
66  return true;
67  }
68  // Check for relative error
69  else if (abs(a - b) <=
71  check_relative_also) {
72  return true;
73  }
74 
75  return false;
76 }
77 
78 /* ************************************************************************* */
79 //3 argument call
80 void print(const Vector& v, const string& s, ostream& stream) {
81  size_t n = v.size();
82 
83  stream << s << "[";
84  for(size_t i=0; i<n; i++) {
85  stream << setprecision(9) << v(i) << (i<n-1 ? "; " : "");
86  }
87  stream << "];" << endl;
88 }
89 
90 /* ************************************************************************* */
91 //1 or 2 argument call
92 void print(const Vector& v, const string& s) {
93  print(v, s, cout);
94 }
95 
96 /* ************************************************************************* */
97 void save(const Vector& v, const string &s, const string& filename) {
98  fstream stream(filename.c_str(), fstream::out | fstream::app);
99  print(v, s + "=", stream);
100  stream.close();
101 }
102 
103 /* ************************************************************************* */
104 bool operator==(const Vector& vec1,const Vector& vec2) {
105  if (vec1.size() != vec2.size()) return false;
106  size_t m = vec1.size();
107  for(size_t i=0; i<m; i++)
108  if(vec1[i] != vec2[i])
109  return false;
110  return true;
111 }
112 
113 /* ************************************************************************* */
114 bool greaterThanOrEqual(const Vector& vec1, const Vector& vec2) {
115  size_t m = vec1.size();
116  for(size_t i=0; i<m; i++)
117  if(!(vec1[i] >= vec2[i]))
118  return false;
119  return true;
120 }
121 
122 /* ************************************************************************* */
123 bool equal_with_abs_tol(const Vector& vec1, const Vector& vec2, double tol) {
124  if (vec1.size()!=vec2.size()) return false;
125  size_t m = vec1.size();
126  for(size_t i=0; i<m; ++i) {
127  if (!fpEqual(vec1[i], vec2[i], tol))
128  return false;
129  }
130  return true;
131 }
132 
133 /* ************************************************************************* */
134 bool equal_with_abs_tol(const SubVector& vec1, const SubVector& vec2, double tol) {
135  if (vec1.size()!=vec2.size()) return false;
136  size_t m = vec1.size();
137  for(size_t i=0; i<m; ++i) {
138  if (!fpEqual(vec1[i], vec2[i], tol))
139  return false;
140  }
141  return true;
142 }
143 
144 /* ************************************************************************* */
145 bool assert_equal(const Vector& expected, const Vector& actual, double tol) {
146  if (equal_with_abs_tol(expected,actual,tol)) return true;
147  cout << "not equal:" << endl;
148  print(expected, "expected");
149  print(actual, "actual");
150  return false;
151 }
152 
153 /* ************************************************************************* */
154 bool assert_inequal(const Vector& expected, const Vector& actual, double tol) {
155  if (!equal_with_abs_tol(expected,actual,tol)) return true;
156  cout << "Erroneously equal:" << endl;
157  print(expected, "expected");
158  print(actual, "actual");
159  return false;
160 }
161 
162 /* ************************************************************************* */
163 bool assert_equal(const SubVector& expected, const SubVector& actual, double tol) {
164  if (equal_with_abs_tol(expected,actual,tol)) return true;
165  cout << "not equal:" << endl;
166  print(static_cast<Vector>(expected), "expected");
167  print(static_cast<Vector>(actual), "actual");
168  return false;
169 }
170 
171 /* ************************************************************************* */
172 bool assert_equal(const ConstSubVector& expected, const ConstSubVector& actual, double tol) {
173  if (equal_with_abs_tol(Vector(expected),Vector(actual),tol)) return true;
174  cout << "not equal:" << endl;
175  print(Vector(expected), "expected");
176  print(Vector(actual), "actual");
177  return false;
178 }
179 
180 /* ************************************************************************* */
181 bool linear_dependent(const Vector& vec1, const Vector& vec2, double tol) {
182  if (vec1.size()!=vec2.size()) return false;
183  bool flag = false; double scale = 1.0;
184  size_t m = vec1.size();
185  for(size_t i=0; i<m; i++) {
186  if((std::abs(vec1[i])>tol && std::abs(vec2[i])<tol) || (std::abs(vec1[i])<tol && std::abs(vec2[i])>tol))
187  return false;
188  if(vec1[i] == 0 && vec2[i] == 0) continue;
189  if (!flag) {
190  scale = vec1[i] / vec2[i];
191  flag = true ;
192  }
193  else if (std::abs(vec1[i] - vec2[i]*scale) > tol) return false;
194  }
195  return flag;
196 }
197 
198 /* ************************************************************************* */
199 Vector ediv_(const Vector &a, const Vector &b) {
200  size_t n = a.size();
201  assert (b.size()==a.size());
202  Vector c(n);
203  for( size_t i = 0; i < n; i++ ) {
204  const double &ai = a(i), &bi = b(i);
205  c(i) = (bi==0.0 && ai==0.0) ? 0.0 : ai/bi;
206  }
207  return c;
208 }
209 
210 /* ************************************************************************* */
211 // imperative version, pass in x
213  const double x0 = v(0);
214  const double x02 = x0*x0;
215 
216  // old code - GSL verison was actually a bit slower
217  const double sigma = v.squaredNorm() - x02;
218 
219  v(0) = 1.0;
220 
221  if( sigma == 0.0 )
222  return 0.0;
223  else {
224  double mu = sqrt(x02 + sigma);
225  if( x0 <= 0.0 )
226  v(0) = x0 - mu;
227  else
228  v(0) = -sigma / (x0 + mu);
229 
230  const double v02 = v(0)*v(0);
231  v = v / v(0);
232  return 2.0 * v02 / (sigma + v02);
233  }
234 }
235 
236 /* ************************************************************************* */
237 pair<double, Vector > house(const Vector &x) {
238  Vector v(x);
239  double beta = houseInPlace(v);
240  return make_pair(beta, v);
241 }
242 
243 /* ************************************************************************* */
244 // Fast version *no error checking* !
245 // Pass in initialized vector of size m or will crash !
246 double weightedPseudoinverse(const Vector& a, const Vector& weights,
247  Vector& pseudo) {
248 
249  size_t m = weights.size();
250  static const double inf = std::numeric_limits<double>::infinity();
251 
252  // Check once for zero entries of a. TODO: really needed ?
253  vector<bool> isZero;
254  for (size_t i = 0; i < m; ++i) isZero.push_back(std::abs(a[i]) < 1e-9);
255 
256  // If there is a valid (a!=0) constraint (sigma==0) return the first one
257  for (size_t i = 0; i < m; ++i) {
258  if (weights[i] == inf && !isZero[i]) {
259  // Basically, instead of doing a normal QR step with the weighted
260  // pseudoinverse, we enforce the constraint by turning
261  // ax + AS = b into x + (A/a)S = b/a, for the first row where a!=0
262  pseudo = Vector::Unit(m,i)*(1.0/a[i]);
263  return inf;
264  }
265  }
266 
267  // Form psuedo-inverse inv(a'inv(Sigma)a)a'inv(Sigma)
268  // For diagonal Sigma, inv(Sigma) = diag(precisions)
269  double precision = 0;
270  for (size_t i = 0; i < m; i++) {
271  double ai = a[i];
272  if (!isZero[i]) // also catches remaining sigma==0 rows
273  precision += weights[i] * (ai * ai);
274  }
275 
276  // precision = a'inv(Sigma)a
277  if (precision < 1e-9)
278  for (size_t i = 0; i < m; i++)
279  pseudo[i] = 0;
280  else {
281  // emul(precisions,a)/precision
282  double variance = 1.0 / precision;
283  for (size_t i = 0; i < m; i++)
284  pseudo[i] = isZero[i] ? 0 : variance * weights[i] * a[i];
285  }
286  return precision; // sum of weights
287 }
288 
289 /* ************************************************************************* */
290 // Slow version with error checking
291 pair<Vector, double>
292 weightedPseudoinverse(const Vector& a, const Vector& weights) {
293  DenseIndex m = weights.size();
294  if (a.size() != m)
295  throw invalid_argument("a and weights have different sizes!");
296  Vector pseudo(m);
297  double precision = weightedPseudoinverse(a, weights, pseudo);
298  return make_pair(pseudo, precision);
299 }
300 
301 /* ************************************************************************* */
302 Vector concatVectors(const std::list<Vector>& vs) {
303  size_t dim = 0;
304  for (const Vector& v : vs) dim += v.size();
305 
306  Vector A(dim);
307  size_t index = 0;
308  for (const Vector& v : vs) {
309  for (int d = 0; d < v.size(); d++) A(d + index) = v(d);
310  index += v.size();
311  }
312 
313  return A;
314 }
315 
316 /* ************************************************************************* */
317 Vector concatVectors(size_t nrVectors, ...)
318 {
319  va_list ap;
320  list<Vector> vs;
321  va_start(ap, nrVectors);
322  for( size_t i = 0 ; i < nrVectors ; i++) {
323  Vector* V = va_arg(ap, Vector*);
324  vs.push_back(*V);
325  }
326  va_end(ap);
327  return concatVectors(vs);
328 }
329 
330 } // namespace gtsam
gtsam::assert_equal
bool assert_equal(const ConstSubVector &expected, const ConstSubVector &actual, double tol)
Definition: Vector.cpp:172
Vector.h
typedef and functions to augment Eigen's VectorXd
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
d
static const double d[K][N]
Definition: igam.h:11
gtsam::ediv_
Vector ediv_(const Vector &a, const Vector &b)
Definition: Vector.cpp:199
gtsam.examples.SFMExample_bal.stream
stream
Definition: SFMExample_bal.py:24
mu
double mu
Definition: testBoundingConstraint.cpp:37
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
b
Scalar * b
Definition: benchVecAdd.cpp:17
gtsam::houseInPlace
double houseInPlace(Vector &v)
Definition: Vector.cpp:212
gtsam::assert_inequal
bool assert_inequal(const Vector &expected, const Vector &actual, double tol)
Definition: Vector.cpp:154
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
isnan
#define isnan(X)
Definition: main.h:93
test_cases::vs
std::vector< Vector3 > vs
Definition: testPose3.cpp:880
gtsam::Vector
Eigen::VectorXd Vector
Definition: Vector.h:39
beta
double beta(double a, double b)
Definition: beta.c:61
sampling::sigma
static const double sigma
Definition: testGaussianBayesNet.cpp:170
A
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:48
gtsam::equal_with_abs_tol
bool equal_with_abs_tol(const SubVector &vec1, const SubVector &vec2, double tol)
Definition: Vector.cpp:134
n
int n
Definition: BiCGSTAB_simple.cpp:1
scale
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
Definition: gnuplot_common_settings.hh:54
gtsam::linear_dependent
bool linear_dependent(const Vector &vec1, const Vector &vec2, double tol)
Definition: Vector.cpp:181
relicense.filename
filename
Definition: relicense.py:57
cholesky::expected
Matrix expected
Definition: testMatrix.cpp:971
x0
static Symbol x0('x', 0)
gtsam::fpEqual
bool fpEqual(double a, double b, double tol, bool check_relative_also)
Definition: Vector.cpp:42
gtsam::save
void save(const Vector &v, const string &s, const string &filename)
Definition: Vector.cpp:97
gtsam::weightedPseudoinverse
pair< Vector, double > weightedPseudoinverse(const Vector &a, const Vector &weights)
Definition: Vector.cpp:292
gtsam::operator==
bool operator==(const Vector &vec1, const Vector &vec2)
Definition: Vector.cpp:104
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
out
std::ofstream out("Result.txt")
gtsam::greaterThanOrEqual
bool greaterThanOrEqual(const Vector &vec1, const Vector &vec2)
Definition: Vector.cpp:114
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
gtsam::concatVectors
Vector concatVectors(size_t nrVectors,...)
Definition: Vector.cpp:317
gtsam
traits
Definition: SFMdata.h:40
precision
cout precision(2)
gtsam::DenseIndex
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:103
std
Definition: BFloat16.h:88
Eigen::VectorBlock
Expression of a fixed-size or dynamic-size sub-vector.
Definition: ForwardDeclarations.h:85
v
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1
min
#define min(a, b)
Definition: datatypes.h:19
gtsam::tol
const G double tol
Definition: Group.h:79
V
MatrixXcd V
Definition: EigenSolver_EigenSolver_MatrixType.cpp:15
gtsam::house
pair< double, Vector > house(const Vector &x)
Definition: Vector.cpp:237
abs
#define abs(x)
Definition: datatypes.h:17
inf
static double inf
Definition: testMatrix.cpp:31
max
#define max(a, b)
Definition: datatypes.h:20
ceres::Vector
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
Definition: gtsam/3rdparty/ceres/eigen.h:38
vec1
RowVectorXd vec1(3)
ceres::sqrt
Jet< T, N > sqrt(const Jet< T, N > &f)
Definition: jet.h:418
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
isinf
#define isinf(X)
Definition: main.h:94
gtsam::print
void print(const Vector &v, const string &s)
Definition: Vector.cpp:92


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:18:23