1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU Lesser General Public License as published
7 //  by the Free Software Foundation; either version 3.0 of the License, or
8 //  any later version.
9 //
10 //  The GPSTk is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with GPSTk; if not, write to the Free Software Foundation,
17 //  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 //  This software was developed by Applied Research Laboratories at the
20 //  University of Texas at Austin.
21 //  Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 /**
40  * @file stl_helpers.hpp
41  * Useful functions that take advantage of STL containers
42  */
43 
44 #ifndef GPSTK_STL_HELPERS_HPP
45 #define GPSTK_STL_HELPERS_HPP
46 
47 #include <cmath>
48 #include <algorithm>
49 #include <list>
50 #include <vector>
51 
52 namespace gpstk
53 {
54       /** @defgroup datastructsgroup STL helpers */
55       //@{
56 
57       /// A simple way to get the max value of a list of numbers
max(const std::list<For> & lst)58    template<class For> For max(const std::list<For>& lst)
59    {
60       return *max_element(lst.begin(), lst.end());
61    }
62 
63       /// A simple way to get the minimum value of a list of numbers
min(const std::list<For> & lst)64    template<class For> For min(const std::list<For>& lst)
65    {
66       return *min_element(lst.begin(), lst.end());
67    }
68 
69       /// ListStats (i.e. Statistics on a list of numbers)
70    template<class bt>
71    struct ListStats
72    {
73          /// number of items used in the statistics taking
74       unsigned n;
75          /// statistics values
76       bt mean, sigma, min, max;
77          /// constructor
ListStatsgpstk::ListStats78       ListStats():n(0),mean(0),sigma(0),min(0),max(0){};
79    };
80 
81       /// Compute the statistics for a list of numbers.
82       /// This algorithm is written to be stable in computing the standard
83       /// deviation for sequences of number with a large mean value.
84       /// (i.e. it doesn't accumulate sum of the value squared.)
stats(const std::list<bt> & lst)85    template<class bt> ListStats<bt> stats(const std::list<bt>& lst)
86    {
87       ListStats<bt> s;
88       bt sum=0, sumsq=0;
89 
90       s.n = lst.size();
91       if (s.n<1)
92          return s;
93 
94       typename std::list<bt>::const_iterator li;
95       li=lst.begin();
96       s.min = s.max = *li;
97       for(; li!=lst.end(); li++)
98       {
99          s.min = std::min(s.min, *li);
100          s.max = std::max(s.max, *li);
101          sum += *li;
102       }
103       s.mean = sum/s.n;
104 
105       if (s.n<2)
106          return s;
107 
108       for(li=lst.begin(); li!=lst.end(); li++)
109       {
110          bt z=*li-s.mean;
111          sumsq += z*z;
112       }
113 
114       s.sigma = std::sqrt( (double)(sumsq/(s.n-1)) );
115 
116       return s;
117    }
118 
119       /// find the index of the first element of a vector with a given value
120       /// @param vec vector<T> in which to look for value
121       /// @param value T value to search for in vector
122       /// @return -1 if value is not found, else index in vector of value
vectorindex(const std::vector<T> & vec,const T & value)123    template <class T> int vectorindex(const std::vector<T>& vec, const T& value)
124    {
125       typename std::vector<T>::const_iterator it;
126       it = std::find(vec.begin(), vec.end(), value);
127       if(it == vec.end()) return -1;
128       return int(it - vec.begin());
129    }
130 
131       /// find the intersection of two vectors - elements common to both vectors
132       /// NB STL algorithms require sorting
133       /// @param v1 first vector to consider
134       /// @param v2 second vector to consider
135       /// @return vector<T> of elements common to v1 and v2
vec_intersect(const std::vector<T> & v1,const std::vector<T> & v2)136    template <class T> std::vector<T> vec_intersect(
137                            const std::vector<T>& v1, const std::vector<T>& v2)
138    {
139       std::vector<T> vinter;
140       typename std::vector<T>::const_iterator it;
141       for(it=v1.begin(); it!=v1.end(); ++it) {
142          if(std::find(v2.begin(), v2.end(), *it) != v2.end())
143             vinter.push_back(*it);
144       }
145       return vinter;
146    }
147 
148       /// find the union minus the intersection of two vectors,
149       /// that is, elements that appear in either one of the two vectors but not both.
150       /// NB STL algorithms require sorting
151       /// @param v1 first vector to consider
152       /// @param v2 second vector to consider
153       /// @return vector<T> of elements not common to v1 and v2
vec_notintersect(const std::vector<T> & v1,const std::vector<T> & v2)154    template <class T> std::vector<T> vec_notintersect(
155                            const std::vector<T>& v1, const std::vector<T>& v2)
156    {
157       std::vector<T> vinter;
158       typename std::vector<T>::const_iterator it;
159       for(it=v1.begin(); it!=v1.end(); ++it) {
160          if(std::find(v2.begin(), v2.end(), *it) == v2.end())
161             vinter.push_back(*it);
162       }
163       for(it=v2.begin(); it!=v2.end(); ++it) {
164          if(std::find(v1.begin(), v1.end(), *it) == v1.end())
165             vinter.push_back(*it);
166       }
167       return vinter;
168    }
169 
170       //@}
171 
172 } // namespace
173 
174 #endif
175