| 
									
										
										
										
											2010-10-14 12:54:38 +08:00
										 |  |  | /* ----------------------------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * GTSAM Copyright 2010, Georgia Tech Research Corporation,  | 
					
						
							|  |  |  |  * Atlanta, Georgia 30332-0415 | 
					
						
							|  |  |  |  * All Rights Reserved | 
					
						
							|  |  |  |  * Authors: Frank Dellaert, et al. (see THANKS for the full author list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * See LICENSE for the license information | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  * -------------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | /**
 | 
					
						
							|  |  |  | * @file    Vector.cpp | 
					
						
							|  |  |  | * @brief   typedef and functions to augment Boost's ublas::vector<double> | 
					
						
							|  |  |  | * @author  Kai Ni | 
					
						
							|  |  |  | * @author  Frank Dellaert | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdarg.h>
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:14:55 +08:00
										 |  |  | #include <limits>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | #include <iostream>
 | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  | #include <fstream>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | #include <sstream>
 | 
					
						
							|  |  |  | #include <iomanip>
 | 
					
						
							| 
									
										
										
										
											2009-11-10 00:47:37 +08:00
										 |  |  | #include <cmath>
 | 
					
						
							| 
									
										
										
										
											2009-11-05 06:19:16 +08:00
										 |  |  | #include <boost/foreach.hpp>
 | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  | #include <boost/optional.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-11-12 01:15:17 +08:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef WIN32
 | 
					
						
							|  |  |  | #include <Windows.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-01 01:24:01 +08:00
										 |  |  | #include <boost/numeric/ublas/io.hpp>
 | 
					
						
							|  |  |  | #include <boost/numeric/ublas/vector_proxy.hpp>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | #include <boost/random/normal_distribution.hpp>
 | 
					
						
							|  |  |  | #include <boost/random/variate_generator.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-20 01:23:19 +08:00
										 |  |  | #include <gtsam/base/Vector.h>
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | using namespace std; | 
					
						
							| 
									
										
										
										
											2010-02-01 01:24:01 +08:00
										 |  |  | namespace ublas = boost::numeric::ublas; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace gtsam { | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void odprintf_(const char *format, ostream& stream, ...) { | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     char    buf[4096], *p = buf; | 
					
						
							|  |  |  |     int     n; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     va_list args; | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |     va_start(args, stream); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     #ifdef WIN32
 | 
					
						
							|  |  |  |     n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
 | 
					
						
							|  |  |  |     #else
 | 
					
						
							|  |  |  |     n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
 | 
					
						
							|  |  |  |     #endif
 | 
					
						
							|  |  |  |     va_end(args); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     #ifdef WIN32
 | 
					
						
							|  |  |  |     OutputDebugString(buf); | 
					
						
							|  |  |  |     #else    
 | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |     stream << buf; | 
					
						
							|  |  |  |     #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-10-22 00:32:11 +08:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |   void odprintf(const char *format, ...) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char    buf[4096], *p = buf; | 
					
						
							|  |  |  |     int     n; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     va_list args; | 
					
						
							|  |  |  |     va_start(args, format); | 
					
						
							|  |  |  |     #ifdef WIN32
 | 
					
						
							|  |  |  |     n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
 | 
					
						
							|  |  |  |     #else
 | 
					
						
							|  |  |  |     n = vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
 | 
					
						
							|  |  |  |     #endif
 | 
					
						
							|  |  |  |     va_end(args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #ifdef WIN32
 | 
					
						
							|  |  |  |     OutputDebugString(buf); | 
					
						
							|  |  |  |     #else
 | 
					
						
							| 
									
										
										
										
											2009-12-12 12:12:24 +08:00
										 |  |  |     cout << buf; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector Vector_( size_t m, const double* const data) { | 
					
						
							|  |  |  |     Vector v(m); | 
					
						
							|  |  |  |     copy(data, data+m, v.data().begin()); | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector Vector_(size_t m, ...) { | 
					
						
							|  |  |  |     Vector v(m); | 
					
						
							|  |  |  |     va_list ap; | 
					
						
							|  |  |  |     va_start(ap, m); | 
					
						
							|  |  |  |     for( size_t i = 0 ; i < m ; i++) { | 
					
						
							|  |  |  |       double value = va_arg(ap, double); | 
					
						
							|  |  |  |       v(i) = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     va_end(ap); | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool zero(const Vector& v) { | 
					
						
							|  |  |  |     bool result = true; | 
					
						
							|  |  |  |     size_t n = v.size(); | 
					
						
							|  |  |  |     for( size_t j = 0 ; j < n ; j++) | 
					
						
							|  |  |  |       result = result && (v(j) == 0.0); | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-11-05 04:59:16 +08:00
										 |  |  |   Vector repeat(size_t n, double value) { | 
					
						
							| 
									
										
										
										
											2010-01-13 00:12:31 +08:00
										 |  |  |     Vector v(n, value); | 
					
						
							| 
									
										
										
										
											2009-10-27 22:21:22 +08:00
										 |  |  |     return v; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 22:42:09 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector delta(size_t n, size_t i, double value) { | 
					
						
							|  |  |  | 	  Vector v = zero(n); | 
					
						
							|  |  |  | 	  v(i) = value; | 
					
						
							|  |  |  | 	  return v; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |   void print(const Vector& v, const string& s, ostream& stream) { | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     size_t n = v.size(); | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |     odprintf_("%s [", stream, s.c_str()); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     for(size_t i=0; i<n; i++) | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |       odprintf_("%g%s", stream, v[i], (i<n-1 ? "; " : "")); | 
					
						
							| 
									
										
										
										
											2010-05-26 16:05:31 +08:00
										 |  |  |     odprintf_("];\n", stream); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void save(const Vector& v, const string &s, const string& filename) { | 
					
						
							| 
									
										
										
										
											2010-05-26 16:05:31 +08:00
										 |  |  |   	fstream stream(filename.c_str(), fstream::out | fstream::app); | 
					
						
							| 
									
										
										
										
											2010-02-24 08:12:10 +08:00
										 |  |  |   	print(v, s + "=", stream); | 
					
						
							|  |  |  |   	stream.close(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool operator==(const Vector& vec1,const Vector& vec2) { | 
					
						
							|  |  |  |     Vector::const_iterator it1 = vec1.begin(); | 
					
						
							|  |  |  |     Vector::const_iterator it2 = vec2.begin(); | 
					
						
							|  |  |  |     size_t m = vec1.size(); | 
					
						
							|  |  |  |     for(size_t i=0; i<m; i++) | 
					
						
							|  |  |  |       if(it1[i] != it2[i]) | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2009-12-01 01:36:34 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool greaterThanOrEqual(const Vector& vec1, const Vector& vec2) { | 
					
						
							|  |  |  | 	  Vector::const_iterator it1 = vec1.begin(); | 
					
						
							|  |  |  | 	  Vector::const_iterator it2 = vec2.begin(); | 
					
						
							|  |  |  | 	  size_t m = vec1.size(); | 
					
						
							|  |  |  | 	  for(size_t i=0; i<m; i++) | 
					
						
							|  |  |  | 		  if(!(it1[i] >= it2[i])) | 
					
						
							|  |  |  | 			  return false; | 
					
						
							|  |  |  | 	  return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool equal_with_abs_tol(const Vector& vec1, const Vector& vec2, double tol) { | 
					
						
							|  |  |  |     Vector::const_iterator it1 = vec1.begin(); | 
					
						
							|  |  |  |     Vector::const_iterator it2 = vec2.begin(); | 
					
						
							|  |  |  |     if (vec1.size()!=vec2.size()) return false; | 
					
						
							| 
									
										
										
										
											2009-11-10 00:47:37 +08:00
										 |  |  |     for(size_t i=0; i<vec1.size(); i++) { | 
					
						
							|  |  |  |     	if(isnan(it1[i]) xor isnan(it2[i])) | 
					
						
							|  |  |  |     		return false; | 
					
						
							|  |  |  |     	if(fabs(it1[i] - it2[i]) > tol) | 
					
						
							|  |  |  |     		return false; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2009-12-08 21:53:33 +08:00
										 |  |  |   bool assert_equal(const Vector& expected, const Vector& actual, double tol) { | 
					
						
							|  |  |  |     if (equal_with_abs_tol(expected,actual,tol)) return true; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     cout << "not equal:" << endl; | 
					
						
							| 
									
										
										
										
											2009-12-08 21:53:33 +08:00
										 |  |  |     print(expected, "expected"); | 
					
						
							|  |  |  |     print(actual, "actual"); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool assert_equal(SubVector expected, SubVector actual, double tol) { | 
					
						
							|  |  |  |     if (equal_with_abs_tol(expected,actual,tol)) return true; | 
					
						
							|  |  |  |     cout << "not equal:" << endl; | 
					
						
							|  |  |  |     print(expected, "expected"); | 
					
						
							|  |  |  |     print(actual, "actual"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool assert_equal(ConstSubVector expected, ConstSubVector actual, double tol) { | 
					
						
							|  |  |  |     if (equal_with_abs_tol(expected,actual,tol)) return true; | 
					
						
							|  |  |  |     cout << "not equal:" << endl; | 
					
						
							|  |  |  |     print(expected, "expected"); | 
					
						
							|  |  |  |     print(actual, "actual"); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-05 07:50:21 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   bool linear_dependent(const Vector& vec1, const Vector& vec2, double tol) { | 
					
						
							|  |  |  |     if (vec1.size()!=vec2.size()) return false; | 
					
						
							|  |  |  |     Vector::const_iterator it1 = vec1.begin(); | 
					
						
							|  |  |  |     Vector::const_iterator it2 = vec2.begin(); | 
					
						
							|  |  |  |     boost::optional<double> scale; | 
					
						
							|  |  |  |     for(size_t i=0; i<vec1.size(); i++) { | 
					
						
							|  |  |  |     	if((fabs(it1[i])>tol&&fabs(it2[i])<tol) || (fabs(it1[i])<tol&&fabs(it2[i])>tol)) | 
					
						
							|  |  |  |     		return false; | 
					
						
							|  |  |  |     	if(it1[i] == 0 && it2[i] == 0) | 
					
						
							|  |  |  |     		continue; | 
					
						
							|  |  |  |     	if (!scale) | 
					
						
							|  |  |  |     		scale = it1[i] / it2[i]; | 
					
						
							|  |  |  |     	else if (fabs(it1[i] - it2[i] * (*scale)) > tol) | 
					
						
							|  |  |  |     		return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return scale.is_initialized(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector sub(const Vector &v, size_t i1, size_t i2) { | 
					
						
							|  |  |  |     size_t n = i2-i1; | 
					
						
							|  |  |  |     Vector v_return(n); | 
					
						
							|  |  |  |     for( size_t i = 0; i < n; i++ ) | 
					
						
							|  |  |  |       v_return(i) = v(i1 + i); | 
					
						
							|  |  |  |     return v_return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2010-02-01 01:24:01 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void subInsert(Vector& big, const Vector& small, size_t i) { | 
					
						
							|  |  |  | 	  ublas::vector_range<Vector> colsubproxy(big, ublas::range (i, i+small.size())); | 
					
						
							|  |  |  | 	  colsubproxy = small; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:14:55 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector emul(const Vector &a, const Vector &b) { | 
					
						
							|  |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  | 		assert (b.size()==n); | 
					
						
							|  |  |  | 		Vector c(n); | 
					
						
							|  |  |  | 		for( size_t i = 0; i < n; i++ ) | 
					
						
							|  |  |  | 			c(i) = a(i)*b(i); | 
					
						
							|  |  |  | 		return c; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 04:59:16 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector ediv(const Vector &a, const Vector &b) { | 
					
						
							|  |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  | 		assert (b.size()==n); | 
					
						
							|  |  |  | 		Vector c(n); | 
					
						
							|  |  |  | 		for( size_t i = 0; i < n; i++ ) | 
					
						
							|  |  |  | 			c(i) = a(i)/b(i); | 
					
						
							|  |  |  | 		return c; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-31 18:29:25 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector ediv_(const Vector &a, const Vector &b) { | 
					
						
							|  |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  | 		assert (b.size()==n); | 
					
						
							|  |  |  | 		Vector c(n); | 
					
						
							|  |  |  | 		for( size_t i = 0; i < n; i++ ) { | 
					
						
							|  |  |  | 			double ai = a(i), bi = b(i); | 
					
						
							|  |  |  | 			c(i) = (bi==0.0 && ai==0.0) ? 0.0 : a(i)/b(i); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return c; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-13 14:14:55 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   double sum(const Vector &a) { | 
					
						
							| 
									
										
										
										
											2009-12-12 05:37:52 +08:00
										 |  |  |   	double result = 0.0; | 
					
						
							| 
									
										
										
										
											2009-11-13 14:14:55 +08:00
										 |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  | 		for( size_t i = 0; i < n; i++ ) | 
					
						
							|  |  |  | 			result += a(i); | 
					
						
							|  |  |  | 		return result; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector reciprocal(const Vector &a) { | 
					
						
							|  |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  |   	Vector b(n); | 
					
						
							|  |  |  |   	for( size_t i = 0; i < n; i++ ) | 
					
						
							|  |  |  |   		b(i) = 1.0/a(i); | 
					
						
							|  |  |  |   	return b; | 
					
						
							|  |  |  |   	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 01:47:23 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  | 	Vector esqrt(const Vector& v) { | 
					
						
							|  |  |  | 		Vector s(v.size()); | 
					
						
							|  |  |  | 		transform(v.begin(), v.end(), s.begin(), ::sqrt); | 
					
						
							|  |  |  | 		return s; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-21 15:38:37 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  | 	Vector abs(const Vector& v) { | 
					
						
							|  |  |  | 		Vector s(v.size()); | 
					
						
							|  |  |  | 		transform(v.begin(), v.end(), s.begin(), ::fabs); | 
					
						
							|  |  |  | 		return s; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-16 13:08:29 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   double max(const Vector &a) { | 
					
						
							|  |  |  |   	return *(std::max_element(a.begin(), a.end())); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 10:04:37 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   double dot(const Vector& a, const Vector& b) { | 
					
						
							|  |  |  |   	size_t n = a.size(); | 
					
						
							|  |  |  | 		assert (b.size()==n); | 
					
						
							|  |  |  | 		double result = 0.0; | 
					
						
							|  |  |  |   	for (size_t i = 0; i < n; i++) | 
					
						
							|  |  |  |   		result += a[i] * b[i]; | 
					
						
							|  |  |  |   	return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 12:01:49 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void scal(double alpha, Vector& x) { | 
					
						
							|  |  |  |   	size_t n = x.size(); | 
					
						
							|  |  |  |   	for (size_t i = 0; i < n; i++) | 
					
						
							|  |  |  |   		x[i] *= alpha; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 10:04:37 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   void axpy(double alpha, const Vector& x, Vector& y) { | 
					
						
							|  |  |  |   	size_t n = x.size(); | 
					
						
							|  |  |  | 		assert (y.size()==n); | 
					
						
							|  |  |  |   	for (size_t i = 0; i < n; i++) | 
					
						
							|  |  |  |   		y[i] += alpha * x[i]; | 
					
						
							| 
									
										
										
										
											2010-02-16 07:53:16 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-02-17 11:29:12 +08:00
										 |  |  |   void axpy(double alpha, const Vector& x, SubVector y) { | 
					
						
							| 
									
										
										
										
											2010-02-16 07:53:16 +08:00
										 |  |  |   	size_t n = x.size(); | 
					
						
							|  |  |  | 		assert (y.size()==n); | 
					
						
							|  |  |  |   	for (size_t i = 0; i < n; i++) | 
					
						
							|  |  |  |   		y[i] += alpha * x[i]; | 
					
						
							| 
									
										
										
										
											2010-01-30 10:04:37 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-17 02:39:39 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector operator/(double s, const Vector& v) { | 
					
						
							|  |  |  |     Vector result(v.size()); | 
					
						
							|  |  |  |     for(size_t i = 0; i < v.size(); i++) | 
					
						
							|  |  |  |       result[i] = s / v[i]; | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  |   // imperative version, pass in x
 | 
					
						
							|  |  |  |   double houseInPlace(Vector &v) { | 
					
						
							|  |  |  | 	  const double x0 = v(0); | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 	  const double x02 = x0*x0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	  // old code - GSL verison was actually a bit slower
 | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  | 	  const double sigma = inner_prod(v,v) - x02; | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  | 	  v(0) = 1.0; | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	  if( sigma == 0.0 ) | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  | 		  return 0.0; | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 	  else { | 
					
						
							|  |  |  | 		  double mu = sqrt(x02 + sigma); | 
					
						
							|  |  |  | 		  if( x0 <= 0.0 ) | 
					
						
							|  |  |  | 			  v(0) = x0 - mu; | 
					
						
							|  |  |  | 		  else | 
					
						
							|  |  |  | 			  v(0) = -sigma / (x0 + mu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		  const double v02 = v(0)*v(0); | 
					
						
							|  |  |  | 		  v = v / v(0); | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  | 		  return 2.0 * v02 / (sigma + v02); | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 	  } | 
					
						
							| 
									
										
										
										
											2010-03-11 23:04:31 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   pair<double, Vector > house(const Vector &x) { | 
					
						
							|  |  |  |   	Vector v(x); | 
					
						
							|  |  |  |   	double beta = houseInPlace(v); | 
					
						
							| 
									
										
										
										
											2010-01-22 02:51:59 +08:00
										 |  |  | 	  return make_pair(beta, v); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2009-10-27 22:21:22 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 	// Fast version *no error checking* !
 | 
					
						
							|  |  |  | 	// Pass in initialized vector of size m or will crash !
 | 
					
						
							|  |  |  | 	double weightedPseudoinverse(const Vector& a, const Vector& weights, | 
					
						
							|  |  |  | 			Vector& pseudo) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:36:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 		size_t m = weights.size(); | 
					
						
							|  |  |  | 		static const double inf = std::numeric_limits<double>::infinity(); | 
					
						
							| 
									
										
										
										
											2009-11-10 12:36:07 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 		// Check once for zero entries of a. TODO: really needed ?
 | 
					
						
							|  |  |  | 		vector<bool> isZero; | 
					
						
							|  |  |  | 		for (size_t i = 0; i < m; ++i) isZero.push_back(fabs(a[i]) < 1e-9); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 		// If there is a valid (a!=0) constraint (sigma==0) return the first one
 | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 		for (size_t i = 0; i < m; ++i) | 
					
						
							|  |  |  | 			if (weights[i] == inf && !isZero[i]) { | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 				pseudo = delta(m, i, 1 / a[i]); | 
					
						
							|  |  |  | 				return inf; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Form psuedo-inverse inv(a'inv(Sigma)a)a'inv(Sigma)
 | 
					
						
							|  |  |  | 		// For diagonal Sigma, inv(Sigma) = diag(precisions)
 | 
					
						
							|  |  |  | 		double precision = 0; | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 		for (size_t i = 0; i < m; i++) { | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 			double ai = a[i]; | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 			if (!isZero[i]) // also catches remaining sigma==0 rows
 | 
					
						
							|  |  |  | 				precision += weights[i] * (ai * ai); | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// precision = a'inv(Sigma)a
 | 
					
						
							|  |  |  | 		if (precision < 1e-9) | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 			for (size_t i = 0; i < m; i++) | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 				pseudo[i] = 0; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			// emul(precisions,a)/precision
 | 
					
						
							|  |  |  | 			double variance = 1.0 / precision; | 
					
						
							| 
									
										
										
										
											2010-01-20 03:04:37 +08:00
										 |  |  | 			for (size_t i = 0; i < m; i++) | 
					
						
							|  |  |  | 				pseudo[i] = isZero[i] ? 0 : variance * weights[i] * a[i]; | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return precision; // sum of weights
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-16 12:57:58 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   // Slow version with error checking
 | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  |   pair<Vector, double> | 
					
						
							|  |  |  |   weightedPseudoinverse(const Vector& a, const Vector& weights) { | 
					
						
							|  |  |  | 	  size_t m = weights.size(); | 
					
						
							| 
									
										
										
										
											2010-01-16 12:57:58 +08:00
										 |  |  | 	  if (a.size() != m) | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  | 		  throw invalid_argument("a and weights have different sizes!"); | 
					
						
							| 
									
										
										
										
											2010-01-16 12:57:58 +08:00
										 |  |  | 	  Vector pseudo(m); | 
					
						
							| 
									
										
										
										
											2010-01-16 14:25:11 +08:00
										 |  |  |   	double precision = weightedPseudoinverse(a, weights, pseudo); | 
					
						
							| 
									
										
										
										
											2010-01-16 12:57:58 +08:00
										 |  |  | 	  return make_pair(pseudo, precision); | 
					
						
							| 
									
										
										
										
											2009-10-29 20:52:27 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector concatVectors(const std::list<Vector>& vs) | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2010-01-20 22:42:05 +08:00
										 |  |  |     size_t dim = 0; | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |     BOOST_FOREACH(Vector v, vs) | 
					
						
							|  |  |  |       dim += v.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Vector A(dim); | 
					
						
							| 
									
										
										
										
											2010-01-20 22:42:05 +08:00
										 |  |  |     size_t index = 0; | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |     BOOST_FOREACH(Vector v, vs) { | 
					
						
							|  |  |  |       for(size_t d = 0; d < v.size(); d++) | 
					
						
							|  |  |  |         A(d+index) = v(d); | 
					
						
							|  |  |  |       index += v.size(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return A; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector concatVectors(size_t nrVectors, ...) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     va_list ap; | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |     list<Vector> vs; | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     va_start(ap, nrVectors); | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |     for( size_t i = 0 ; i < nrVectors ; i++) { | 
					
						
							|  |  |  |     	Vector* V = va_arg(ap, Vector*); | 
					
						
							|  |  |  |       vs.push_back(*V); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     va_end(ap); | 
					
						
							| 
									
										
										
										
											2009-12-18 14:11:19 +08:00
										 |  |  |     return concatVectors(vs); | 
					
						
							| 
									
										
										
										
											2009-08-22 06:23:24 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |   Vector rand_vector_norm(size_t dim, double mean, double sigma) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     boost::normal_distribution<double> norm_dist(mean, sigma); | 
					
						
							|  |  |  |     boost::variate_generator<boost::minstd_rand&, boost::normal_distribution<double> > norm(generator, norm_dist); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     Vector v(dim); | 
					
						
							|  |  |  |     Vector::iterator it_v; | 
					
						
							|  |  |  |     for(it_v=v.begin(); it_v!=v.end(); it_v++) | 
					
						
							|  |  |  |       *it_v = norm(); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     return v; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   /* ************************************************************************* */ | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | } // namespace gtsam
 |