How to iterate through variable members of a class C++ - c++

I'm currently trying to do a complicated variable correction to a bunch of variables (based on normalizing in various phase spaces) for some data that I'm reading in. Since each correction follows the same process, I was wondering if there would be anyway to do this iteratively rather than handle each variable by itself (since I need to this for about 18-20 variables). Can C++ handle this? I was told by someone to try this in python but I feel like it could be done in C++ in some way... I'm just hitting a wall!
To give you an idea, given something like:
class VariableClass{
public :
//each object of this class represents an event for this particlular data set
//containing the following variables
double x;
double y;
double z;
}
I want to do something along the lines of:
for (int i=0; i < num_variables; i++)
{
for (int j=0; j < num_events; j++)
{
//iterate through events
}
//correct variable here, then move on to next one
}
Thanks in advance for any advice!!!

I'm assuming your member variables will not all have the same type. Otherwise you can just throw them into a container. If you have C++11, one way you could solve this problem is a tuple. With some template metaprogramming you can simulate a loop over all elements of the tuple. The function std::tie will build a tuple with references to all of your members that you can "iterate" like this:
struct DoCorrection
{
template<typename T>
void operator()(T& t) const { /* code goes here */ }
};
for_each(std::tie(x, y, z), DoCorrection());
// see linked SO answer for the detailed code to make this special for_each work.
Then, you can specialize operator() for each member variable type. That will let you do the appropriate math automatically without manually keeping track of the types.

taken from glm (detail vec3.incl)
template <typename T>
GLM_FUNC_QUALIFIER typename tvec3<T>::value_type &
tvec3<T>::operator[]
(
size_type i
)
{
assert(i < this->length());
return (&x)[i];
}
this would translate to your example:
class VariableClass{
public :
//each object of this class represents an event for this particlular data
double x;
double y;
double z;
double & operator[](int i) {
assert(i < 3);
return (&x)[i];
}
}
VariableClass foo();
foo.x = 2.0;
std::cout << foo[0] << std::endl; // => 2.0
Althought i would recomment glm, if it is just about vector math.

Yes, just put all your variables into a container, like std::vector, for example.

http://en.cppreference.com/w/cpp/container/vector
I recommend spending some time reading about all the std classes. There are many containers and many uses.

In general you cannot iterate over members without relying on implementation defined things like padding or reordering of sections with different access qualifiers (literally no compiler does the later - it is allowed though).
However, you can use a the generalization of a record type: a std::tuple. Iterating a tuple isn't straight-forward but you will find plenty of code that does it. The worst here is the loss of named variables, which you can mimic with members.
If you use Boost, you can use Boost.Fusion's helper-macro BOOST_FUSION_ADAPT_STRUCT to turn a struct into a Fusion sequence and then you can use it with Fusion algorithms.

Related

Templates with <class Comparable> in C++

I am attempting to compare algorithms. I am not familiar with the C++. I want to create a main where I will include the code below as a header. I don't completely understand what "template class Comparable" is though.
#include <vector>
using namespace std;
template <class Comparable>
void SelectionSort(vector<Comparable> & nums, int low, int high)
{
for (int i = low; i <= high-1; i++) {
int indexOfMin = i; // traverse the list to
for (int j = i+1; j <= high; j++) { // find the index of the
if (nums[j] < nums[indexOfMin]) { // next smallest item
indexOfMin = j;
}
}
Comparable temp = nums[i]; // swap the next smallest
nums[i] = nums[indexOfMin]; // item into its correct
nums[indexOfMin] = temp; // position
}
}
template <class Comparable> void SelectionSort(vector<Comparable> & nums)
{
SelectionSort(nums, 0, nums.size()-1);
}
Your main sort function there looks like this (snipping the "template" part for now):
void SelectionSort(vector<Comparable> & nums)
{
SelectionSort(nums, 0, nums.size()-1);
}
Looks like a normal sort function that acts on a vector of Comparables. But what is a Comparable? Well imagine if "Comparable" were nothing more than an alias for "int" (it's not, but imagine). Then you'd have this:
void SelectionSort(vector<int> & nums)
{
SelectionSort(nums, 0, nums.size()-1);
}
This is ordinary C++ code. It declares and defines a function that sorts a vector of ints. Pretty straightforward.
Comparable doesn't have a standard meaning like that. It is a term invented by the code in your question. It is declared by the text template <class Comparable>, approximately the way a variable is declared. It is something like a "type variable". An ordinary variable represents one of many values; a type variable represents one of many types.
template <class Comparable> void SelectionSort(vector<Comparable> & nums)
{
SelectionSort(nums, 0, nums.size()-1);
}
This code declares that Comparable is not automatically int, or float, or std::string, but rather may be any type at all. To use this function you must specify what type you want when you call the function. You can do it explicitly:
std::vector<int> someints;
SelectionSort<int>(someints);
(And this will make "Comparable" mean "int" after all, within that one call.)
Or you can leave out that extra specification and hope for the compiler to figure it out:
std::vector<int> someints;
SelectionSort(someints);
And you can use the same template for different types as much as you want; it is not "spent" in any sense by one use:
std::vector<int> someints, moreints;
std::vector<float> somefloats;
SelectionSort(someints);
SelectionSort(somefloats);
SelectionSort(moreints);
For a simple purpose like this, you can imagine that SelectionSort is a function that works on many types, not just one. But actually it is not a function. It is a whole family of potential functions, some of which may be instantiated by the compiler. The code just above calls SelectionSort three times, but with only two Comparable types, and so behind the scenes it creates two actual functions.
I've been talking about Comparable as a variable, but it can't vary WITHIN an instance of the template. You can't do Comparable=float within SelectionSort<int> or anything like that. It varies from one instance of the template to another, not within one instance. When the template is instantiated as a real function, Comparable is replaced by the type that was specified for it and then forgotten; that function doesn't "know" it is an instance of the template. It's just a function that happens to have angle brackets in its name. I think.
There are indeed some very powerful, complicated, mind-bending things that can be done with templates. But you probably don't need to know much about those for your purpose.
One more important basic point, though, is that there are also template classes. std::vector itself is one of them. They work in a roughly analogous way to template functions like SelectionSort: the header <vector> declares the vector template only once for all types, but then you can say std::vector<int> and then later std::vector<SomeClassIMade> and so on, and thereby automatically instantiate two (or more) actual classes. All these classes will work like a C++ vector is supposed to, but each one will only know how to handle its own specified element type, and will not understand any other.

C++ looping through a vector of structure

say I have
struct S {
double A;
double B;
double C;
};
and
std::vector<S> vecS(10);
I am trying to write a generic function void F(std::vector<S> vecS,structure S.x) such that the following computation can happen
F(std::vector<S> vecS, structure S.x) {
for(i=1;i<10;i++)
vecS[0].x += vecS[i].x;
// note the structure does not have memeber "x"
// I want to give that as a generic input to access A,B or C
}
The above code is not correct code, but I am just trying to demonstrate what I am trying to compute.
What I am trying to compute is loop over the vector of structs for a specific element. Is this possible in a simple nice way? Can someone please give me some pointers how to access a member of a structure in a generic way (maybe that is what I need to write this function).
Thanks in advance.
What you need is a pointer to member:
void F( std::vector<S> &vecS, double S::*ptr )
{
for(i=1;i<10;i++)
vecS[0].*ptr += vecS[i].*ptr;
}
// now call for A
F( vec, &S::A );
If you need it to work with different types, not only double as in this case, use template.
PS I did not notice first, but you have to pass vector as reference, as you modifying element in it.
Well, it's not generic in the sense that you have a vector hardcoded, but let's ignore that for a second.
What you want is a pointer-to-member:
template <typename T, typename M>
F(std::vector<S> vecS, M T::* member) {
for(i=1;i<10;i++)
vecS[0].*member += vecS[i].*member;
}
Call as F(vec, &myClass::A)
The concept you are looking for is called a pointer to member. You can't use the exact syntax as you have written, and pointer to member syntax is rather ugly and not commonly used. But here's the basics.
double S::*x = &S::A;
vecS[0]->*x += vecS[i]->*x
See the following for more details:
http://en.cppreference.com/w/cpp/language/operator_member_access#Built-in_pointer-to-member_access_operators
http://en.cppreference.com/w/cpp/language/pointer
Also, unrelated to your question, but you need to declare the type of your loop variable i. Currently, it is undefined.

Cache gauss points for numerical integration in c++

This is a question on what people think the best way to lay out my class structure for my problem. I am doing some numerical analysis and require certain "elements" to be integrated. So I have created a class called "BoundaryElement" like so
class BoundaryElement
{
/* private members */
public:
integrate(Point& pt);
};
The key function is 'integrate' which I need to evaluate for a whole variety of different points. What happens is that, depending on the point, I need to use a different number of integration points and weights, which are basically vectors of numbers. To find these, I have a class like so:
class GaussPtsWts
{
int numPts;
double* gaussPts;
double* gaussWts;
public:
GaussPtsWts(const int n);
GaussPtsWts(const GaussPtsWts& rhs);
~GaussPtsWts();
GaussPtsWts& operator=(const GaussPtsWts& rhs);
inline double gwt(const unsigned int i)
{
return gaussWts[i];
}
inline double gpt(const unsigned int i)
{
return gaussPts[i];
}
inline int numberGPs()
{
return numGPs;
}
};
Using this, I could theoretically create a GaussPtsWts instance for every call to the integrate function. But I know that I maybe using the same number of gauss points many times , and so I would like to cache this data. I'm not very confident on how this might be done - potentially a std::map which is a static member of the BoundaryElement class? If people could shed any light on this I would be very grateful. Thanks!
I had a similar issue once and used a map (as you suggested). What I would do is change the GaussPtsWts to contain the map:
typedef std::map<int, std::vector<std::pair<double, double>>> map_type;
Here I've taken your two arrays of the points and weights and put them into a single vector of pairs - which should apply if I remember my quadrature correctly. Feel free to make a small structure of the point and weight to make it more readable.
Then I'd create a single instance of the GaussPtsWts and store a reference to it in each BoundaryElement. Or perhaps a shared_ptr depending on how you like it. You'd also need to record how many points you are using.
When you ask for a weight, you might have something like this:
double gwt(const unsigned int numGPs, const unsigned int i)
{
map_type::const_iterator found = themap.find(numGPs);
if(found == themap.end())
calculatePoints(numGPs);
return themap[numGPs][i].first;
}
Alternatively you could mess around with templates with an integer parameter:
template <int N>
class GaussPtsWts...

How to take pair-like function arguments

I'm writing a class which will be used to perform some calculations on a set of values, with scaling based on a per-value weight. The values and weights are supplied to the class' constructor. The class will be part of an internal library, and so I want to put as few restrictions as possible on the clients data structures - some clients will use vectors of structs or std::pairs, another separate OpenCV matrixes. During development I've taken start/end iterators and relied on the pair mechanism (val = it->first, weight = it->second).
How could this be done better, without too much hassle for the programmer on the other end? Generally, what is considered best practise when having this sort of multi-dimensional input?
Iterators are fine. However, relying on the types having public members called first and second is a pretty big restriction.
In C++0x, access to std::pair members will be unified with the access patterns of std::tuple, via a get function. This would allow you to overload and specialize the get function for arbitrary types:
#include <iostream>
#include <utility>
template <class T>
void print(const T& data)
{
using std::get;
std::cout << get<0>(data) << ' ' << get<1>(data) << '\n';
}
struct Coord
{
int x, y;
};
template <unsigned>
int get(const Coord&);
template <>
int get<0>(const Coord& c) { return c.x; }
template <>
int get<1>(const Coord& c) { return c.y; }
int main()
{
print(std::make_pair(1, 2));
Coord coord = {4, 5};
print(coord);
}
In case your standard library doesn't have get for pair, then boost's tuple library seems to have it.
That situation is pretty much what templates are in the language for.

A proper way to create a matrix in c++

I want to create an adjacency matrix for a graph. Since I read it is not safe to use arrays of the form matrix[x][y] because they don't check for range, I decided to use the vector template class of the stl. All I need to store in the matrix are boolean values. So my question is, if using std::vector<std::vector<bool>* >* produces too much overhead or if there is a more simple way for a matrix and how I can properly initialize it.
EDIT: Thanks a lot for the quick answers. I just realized, that of course I don't need any pointers. The size of the matrix will be initialized right in the beginning and won't change until the end of the program. It is for a school project, so it would be good if I write "nice" code, although technically performance isn't too important. Using the STL is fine. Using something like boost, is probably not appreciated.
Note that also you can use boost.ublas for matrix creation and manipulation and also boost.graph to represent and manipulate graphs in a number of ways, as well as using algorithms on them, etc.
Edit: Anyway, doing a range-check version of a vector for your purposes is not a hard thing:
template <typename T>
class BoundsMatrix
{
std::vector<T> inner_;
unsigned int dimx_, dimy_;
public:
BoundsMatrix (unsigned int dimx, unsigned int dimy)
: dimx_ (dimx), dimy_ (dimy)
{
inner_.resize (dimx_*dimy_);
}
T& operator()(unsigned int x, unsigned int y)
{
if (x >= dimx_ || y>= dimy_)
throw std::out_of_range("matrix indices out of range"); // ouch
return inner_[dimx_*y + x];
}
};
Note that you would also need to add the const version of the operators, and/or iterators, and the strange use of exceptions, but you get the idea.
Best way:
Make your own matrix class, that way you control every last aspect of it, including range checking.
eg. If you like the "[x][y]" notation, do this:
class my_matrix {
std::vector<std::vector<bool> >m;
public:
my_matrix(unsigned int x, unsigned int y) {
m.resize(x, std::vector<bool>(y,false));
}
class matrix_row {
std::vector<bool>& row;
public:
matrix_row(std::vector<bool>& r) : row(r) {
}
bool& operator[](unsigned int y) {
return row.at(y);
}
};
matrix_row& operator[](unsigned int x) {
return matrix_row(m.at(x));
}
};
// Example usage
my_matrix mm(100,100);
mm[10][10] = true;
nb. If you program like this then C++ is just as safe as all those other "safe" languages.
The standard vector does NOT do range checking by default.
i.e. The operator[] does not do a range check.
The method at() is similar to [] but does do a range check.
It will throw an exception on out of range.
std::vector::at()
std::vector::operator[]()
Other notes:
Why a vector<Pointers> ?
You can quite easily have a vector<Object>. Now there is no need to worry about memory management (i.e. leaks).
std::vector<std::vector<bool> > m;
Note: vector<bool> is overloaded and not very efficient (i.e. this structure was optimized for size not speed) (It is something that is now recognized as probably a mistake by the standards committee).
If you know the size of the matrix at compile time you could use std::bitset?
std::vector<std::bitset<5> > m;
or if it is runtime defined use boost::dynamic_bitset
std::vector<boost::dynamic_bitset> m;
All of the above will allow you to do:
m[6][3] = true;
If you want 'C' array performance, but with added safety and STL-like semantics (iterators, begin() & end() etc), use boost::array.
Basically it's a templated wrapper for 'C'-arrays with some NDEBUG-disable-able range checking asserts (and also some std::range_error exception-throwing accessors).
I use stuff like
boost::array<boost::array<float,4>,4> m;
instead of
float m[4][4];
all the time and it works great (with appropriate typedefs to keep the verbosity down, anyway).
UPDATE: Following some discussion in the comments here of the relative performance of boost::array vs boost::multi_array, I'd point out that this code, compiled with g++ -O3 -DNDEBUG on Debian/Lenny amd64 on a Q9450 with 1333MHz DDR3 RAM takes 3.3s for boost::multi_array vs 0.6s for boost::array.
#include <iostream>
#include <time.h>
#include "boost/array.hpp"
#include "boost/multi_array.hpp"
using namespace boost;
enum {N=1024};
typedef multi_array<char,3> M;
typedef array<array<array<char,N>,N>,N> C;
// Forward declare to avoid being optimised away
static void clear(M& m);
static void clear(C& c);
int main(int,char**)
{
const clock_t t0=clock();
{
M m(extents[N][N][N]);
clear(m);
}
const clock_t t1=clock();
{
std::auto_ptr<C> c(new C);
clear(*c);
}
const clock_t t2=clock();
std::cout
<< "multi_array: " << (t1-t0)/static_cast<float>(CLOCKS_PER_SEC) << "s\n"
<< "array : " << (t2-t1)/static_cast<float>(CLOCKS_PER_SEC) << "s\n";
return 0;
}
void clear(M& m)
{
for (M::index i=0;i<N;i++)
for (M::index j=0;j<N;j++)
for (M::index k=0;k<N;k++)
m[i][j][k]=1;
}
void clear(C& c)
{
for (int i=0;i<N;i++)
for (int j=0;j<N;j++)
for (int k=0;k<N;k++)
c[i][j][k]=1;
}
What I would do is create my own class for dealing with matrices (probably as an array[x*y] because I'm more used to C (and I'd have my own bounds checking), but you could use vectors or any other sub-structure in that class).
Get your stuff functional first then worry about how fast it runs. If you design the class properly, you can pull out your array[x*y] implementation and replace it with vectors or bitmasks or whatever you want without changing the rest of the code.
I'm not totally sure, but I thing that's what classes were meant for, the ability to abstract the implementation well out of sight and provide only the interface :-)
In addition to all the answers that have been posted so far, you might do well to check out the C++ FAQ Lite. Questions 13.10 - 13.12 and 16.16 - 16.19 cover several topics related to rolling your own matrix class. You'll see a couple of different ways to store the data and suggestions on how to best write the subscript operators.
Also, if your graph is sufficiently sparse, you may not need a matrix at all. You could use std::multimap to map each vertex to those it connects.
my favourite way to store a graph is vector<set<int>>; n elements in vector (nodes 0..n-1), >=0 elements in each set (edges). Just do not forget adding a reverse copy of every bi-directional edge.
Consider also how big is your graph/matrix, does performance matter a lot? Is the graph static, or can it grow over time, e.g. by adding new edges?
Probably, not relevant as this is an old question, but you can use the Armadillo library, which provides many linear algebra oriented data types and functions.
Below is an example for your specific problem:
// In C++11
Mat<bool> matrix = {
{ true, true},
{ false, false},
};
// In C++98
Mat<bool> matrix;
matrix << true << true << endr
<< false << false << endr;
Mind you std::vector doesn't do range checking either.