I've tried something like this:
vector<bool> x(10, 0);
vector<vector<bool> > hello(10, x);
/*some modifications on hello*/
memset(&hello, 0, sizeof(hello));
And my program compiles, but it breaks. Any idea how I can do this operation as quickly as possible? I know that the memset probably isn't working because of the nested vector, but I'm not sure how to accomplish this task.
I would use this, which reuses the x variable you declared in the question.
std::fill(hello.begin(), hello.end(), x);
for(auto& bv : hello)
std::fill(begin(bv), end(bv), false);
Or if you want to use x as the prototype
std::fill(begin(hello), end(hello), x);
With the code you have, I'd write …
for( auto& v : hello ) { v = x; }
assuming x has remained as all-zeros. It's clear enough and avoids dragging in <algorithm>.
Hewever, it will probably be faster to change the representation of your bit matrix, from a vector of vectors to a single vector, or if it's fixed size, to a single bitset.
Related
I thought that a cool way of using vectors could be to have one vector class template hold an two separate int variables for x/y-coordinates to graph.
example:
std::vector<int, int> *name*;
// First int. being the x-intercept on a graph
// Second int. being the y-intercept on a graph
(I also understand that I could just make every even/odd location or two separate vectors to classify each x/y-coordinate, but for me I would just like to see if this could work)
However, after making this vector type, I came across an issue with assigning which int within the vector will be written to or extracted from. Could anyone tell me how to best select and std::cout both x/y ints appropriately?
P.S. - My main goal, in using vectors this way, is to make a very basic graph output to Visual Studio terminal. While being able to change individual x/y-intercepts by 'selecting' and changing if needed. These coordinates will be outputted to the terminal via for/while loops.
Also, would anyone like to list out different ways to best make x/y-coordinates with different containers?
Your question rather broad, in other words it is asking for a bit too much. I will just try to give you some pointers from which you can work your way to what you like.
A) equidistant x
If your x values are equidistant, ie 0, 0.5, 1, 1.5 then there is no need to store them, simply use a
std::vector<int> y;
if the number of variables is not known at compile time, otherwise a
std::array<int,N> y;
B) arbitrary x
There are several options that depend on what you actually want to do. For simply storing (x,y)-pairs and printing them on the screen, they all work equally well.
map
std::map<int,int> map_x_to_y = { { 1,1}, {2,4}, {3,9}};
// print on screen
for (const auto& xy : map_x_to_y) {
std::cout << xy.first << ":" xy.second;
}
a vector of pairs
std::vector<std::pair<int,int>> vector_x_and_y = { { 1,1}, {2,4}, {3,9}};
Printing on screen is actually the same as with map. The advantage of the map is that it has its elements ordered, while this is not the case for the vector.
C) not using any container
For leightweight calculations you can consider to not store the (xy) pairs at all, but simply use a function:
int fun(int x) { return x*x; }
TL;DR / more focussed
A vector stores one type. You cannot have a std::vector<int,int>. If you look at the documentation of std::vector you will find that the second template parameter is an allocator (something you probably dont have to care about for some time). If you want to store two values as one element in a vector you either have to use std::vector<std::pair<double,double>> or a different container.
PS
I used std::pair in the examples above. However, I do consider it as good practice to name things whenever I can and leave std::pair for cases when I simply cannot give names better than first and second. In this spirit you can replace std::pair in the above examples with a
struct data_point {
int x;
int y;
};
I'm a newbie in C++, I was learning to code in python.
I believe the solution is simple but I have no idea how to do it.
Here is what I was trying to do in C++ (not working):
int createBoard(int x, int y) {
int l[x];
int board[y, l[x]];
return board;
}
int main() {
int x = 5;
int y = 6;
board = createBoard(x,y);
return 0;
}
Here is what I wanted to replicate (working, but in python):
def createBoard(x,y):
length = [i for i in range(0,10)]
area = [y,length]
return area
area = createBoard(5,6)
Basically I want to create a function that returns an array with the y value and an array counting until x.
As far as I understood from your Python code, you want to create a 2D array. For a complete beginner in C++ that might be a challenging task. Many recommend to use std::vector and they are right but 2D "array" using such container could be very slow. So this example will work but undesirable in the future case when you gain more experience in C++:
#include <vector>
std::vector< std::vector<int> > createBoard(size_t x, size_t y)
{
return std::vector< std::vector<int> >(x, std::vector<int>(y));
}
So if you want to use a more efficient way of creating 2D arrays, see this example:
LINK
Translating code line by line is almost guaranteed to fail. You better do it in two steps: 1) fully understand what code in language A does. 1a) forget about the code in language A. 2) Write the same in language B.
I am not very proficient with python so I start from this:
Basically I want to create a function that returns an array with the y
value and an array counting until x.
You declared the function to return a single int. A single int is not two arrays.
Next, this
int l[x];
Is not standard c++ because x is not a compile time constant. Some compilers offer it as an extension, but there is no reason to use it because c++ has std::vector.
Then, this
int board[y, l[x]];
is problematic in multiple ways. l[x] is accessing an element in the array l that is out of bounds. Valid indexes are 0 till x-1 because l has x elements. Accessing the array out of bounds is undefined behaviour. We could stop at this point, because in the presece of undefined behaviour anything can happen. However, y, l[x] invokes the comma operator. It evaluates both sides and results in the right operand. Then you again have the same problem, l[x] is no compile time constant.
In this place I had code in c++, but it turned out that I completely misunderstood what your code is supposed to do. I'll leave the answer and refer you to others for the solution.
There are several problems with your code. The main one is that the Python array area contains objects of two different types: The first is the integer y, the second is the array length. All elements of a C++ array must have the same type.
Depending on what you want to use it for, you can replace the board array with a std::pair. This is an object containing two elements of different types.
Also, in C++ arrays with non-constant lengths must be dynamically created. Either using the new operator or (better) using std::unique_ptr. (Or you might want to use std::vector instead.)
Here's a small C++ program that does something like what you want to do:
#include <utility>
#include <memory>
auto createBoard(int x, int y) {
return std::make_pair(y, std::make_unique<int[]>(x));
}
int main() {
auto board = createBoard(5,6);
return 0;
}
(This will only work if your compiler supports C++14 or newer.)
But this is actually rather much above "newbie" level, and I doubt that you will find it very useful.
It would be better to start with a specification of what your program should do, rather than try to translate code from Python.
EDIT
Same code with std::vector instead of a dynamic array:
#include <utility>
#include <vector>
auto createBoard(int x, int y) {
return std::make_pair(y, std::vector<int>(x));
}
int main() {
auto board = createBoard(5,6);
return 0;
}
I'd like to convert std::vector<std::vector<float>> into std::vector<float2>. The direct way is like this:
std::vector<std::vector<float>> pts;
std::vector<float> p1{1.,2.};
std::vector<float> p2{2.,3.};
pts.push_back(p1);
pts.push_back(p2);
std::vector<float2> lattice;
for (auto p : pts){
p_ = make_float2(p[0],p[1]);
lattice.push_back(p_);
}
Here float2 is cuda vector types, it is defined like this (not 100% sure):
struct __device_builtin__ __align__(8) float2
{
float x, y ;
};
There is any other quick method?
There are a couple of things you can do. 1 is use a type that means you know that there will always be 2 elements, such as:
std::vector<std::array<float, 2>>
or
std::vector<std::pair<float, float>>
This will mean you don't need to check that your internal vector is the right size before creating each point for safe code.
Secondly, reserve the right amount of space in your lattice vector before you begin emplacing back, this will mean that you will never have to resize and you won't waste time copying:
std::vector<float2> lattice;
lattice.reserve(pts.size());
for (auto p : pts){
lattice.emplace_back(make_float2(p[0],p[1]));
}
Note, this requires that the float2 structure supports move (which it will based on the definition provided).
If you run a test on these two methods as done here. You will see that you can heavily reduce the time it will take. In the example that is linked, over 10000 points, the time is roughly 1/5th of the original time with my suggested changes.
I am using vector of vector to simulate a 2D array. In order to reuse this 2D array, sometimes I need to reset all its elements to zero or some default value. I know for a simple 1D vector I can do:
std::fill(v.begin(), v.end(), 0);
How to do that efficiently for a vector<vector<int>>? I hope to find a solution without using for loops but more akin to some memset variant. I also don't want to incur any memory allocation and deallocation since my intent was to reuse the existing allocated memory.
Note that I am assuming each vector's size is fixed and known to me: vector<vector<int>> v(const_max_size, vector<int> (const_max_size, 0));. How to reset v's elements to zero?
NOTE: What I mean by not using for loops is that I don't want to iterate over all the 2D elements using subscripts like v[i][j] to assign them the value.
I hope to find a solution without using for loops ...
Well, either you do a loop explicitly or use something that loops implicitly. Nothing wrong with explicit loops:
for (auto& sub : v) {
std::fill(sub.begin(), sub.end(), 0);
}
I guess technically if you want to avoid a loop you could use:
std::for_each(v.begin(), v.end(),
[](auto& sub) {
std::fill(sub.begin(), sub.end(), 0);
});
I know I am going to get flack for this answer, but I am sure there is nothing faster:
for(auto& x : v) memset(&x[0],0,sizeof(int)*x.size());
memset is highly optimized for setting to 0.
I am doing some C++ computational mechanics (don't worry, no physics knowledge required here) and there is something that really bothers me.
Suppose I want to represent a 3D math Vector (nothing to do with std::vector):
class Vector {
public:
Vector(double x=0., double y=0., double z=0.) {
coordinates[0] = x;
coordinates[1] = y;
coordinates[2] = z;
}
private:
double coordinates[3];
};
So far so good. Now I can overload operator[] to extract coordinates:
double& Vector::operator[](int i) {
return coordinates[i] ;
}
So I can type:
Vector V;
… //complex computation with V
double x1 = V[0];
V[1] = coord2;
The problem is, indexing from 0 is NOT natural here. I mean, when sorting arrays, I don't mind, but the fact is that the conventionnal notation in every paper, book or whatever is always substripting coordinates beginning with 1.
It may seem a quibble but the fact is that in formulas, it always takes a double-take to understand what we are taking about. Of course, this is much worst with matrices.
One obvious solution is just a slightly different overloading :
double& Vector::operator[](int i) {
return coordinates[i-1] ;
}
so I can type
double x1 = V[1];
V[2] = coord2;
It seems perfect except for one thing: this i-1 subtraction which seems a good candidate for a small overhead. Very small you would say, but I am doing computationnal mechanics, so this is typically something we couldn't afford.
So now (finally) my question: do you think a compiler can optimize this, or is there a way to make it optimize ? (templates, macro, pointer or reference kludge...)
Logically, in
double xi = V[i];
the integer between the bracket being a literal most of the time (except in 3-iteration for loops), inlining operator[] should make it possible, right ?
(sorry for this looong question)
EDIT:
Thanks for all your comments and answers
I kind of disagree with people telling me that we are used to 0-indexed vectors.
From an object-oriented perspective, I see no reason for a math Vector to be 0-indexed because implemented with a 0-indexed array. We're not suppose to care about the underlying implementation. Now, suppose I don't care about performance and use a map to implement Vector class. Then I would find it natural to map '1' with the '1st' coordinate.
That said I tried out with 1-indexed vectors and matrices, and after some code writing, I find it not interacting nicely every time I use an array around. I thougth Vector and containers (std::array,std::vector...) would not interact often (meaning, transfering data between one another), but it seems I was wrong.
Now I have of a solution that I think is less controversial (please give me your opinion) :
Every time I use a Vector in some physical context, I think of using an enum :
enum Coord {
x = 0,
y = 1,
z = 2
};
Vector V;
V[x] = 1;
The only disadvantage I see being that these x,y and z can be redefined without enven a warning...
This one should be measured or verified by looking at the disassembly, but my guess is: The getter function is tiny and its arguments are constant. There is a high chance the compiler will inline the function and constant-fold the subtraction. In that case the runtime cost would be zero.
Why not to try this:
class Vector {
public:
Vector(double x=0., double y=0., double z=0.) {
coordinates[1] = x;
coordinates[2] = y;
coordinates[3] = z;
}
private:
double coordinates[4];
};
If you are not instantiating your object in quantities of millions, then the memory waist might be affordable.
Have you actually profiled it or examined the generated code? That's how this question is answered.
If the operator[] implementation is visible then this is likely to be optimized to have zero overhead.
I recommend you define this in the header (.h) for your class. If you define it in the .cpp then the compiler can't optimize as much. Also, your index should not be an "int" which can have negative values... make it a size_t:
class Vector {
// ...
public:
double& operator[](const size_t i) {
return coordinates[i-1] ;
}
};
You cannot say anything objective about performance without benchmarking. On x86, this subtraction can be compiled using relative addressing, which is very cheap. If operator[] is inlined, then the overhead is zero—you can encourage this with inline or with compiler-specific instructions such as GCC’s __attribute__((always_inline)).
If you must guarantee it, and the offset is a compile-time constant, then using a template is the way to go:
template<size_t I>
double& Vector::get() {
return coordinates[i - 1];
}
double x = v.get<1>();
For all practical purposes, this is guaranteed to have zero overhead thanks to constant-folding. You could also use named accessors:
double Vector::x() const { return coordinates[0]; }
double Vector::y() const { return coordinates[1]; }
double Vector::z() const { return coordinates[2]; }
double& Vector::x() { return coordinates[0]; }
double& Vector::y() { return coordinates[1]; }
double& Vector::z() { return coordinates[2]; }
And for loops, iterators:
const double* Vector::begin() const { return coordinates; }
const double* Vector::end() const { return coordinates + 3; }
double* Vector::begin() { return coordinates; }
double* Vector::end() { return coordinates + 3; }
// (x, y, z) -> (x + 1, y + 1, z + 1)
for (auto& i : v) ++i;
Like many of the others here, however, I disagree with the premise of your question. You really should simply use 0-based indexing, as it is more natural in the realm of C++. The language is already very complex, and you need not complicate things further for those who will maintain your code in the future.
Seriously, benchmark this all three ways (ie, compare the subtraction and the double[4] methods to just using zero-based indices in the caller).
It's entirely possible you'll get a huge win from forcing 16-byte alignment on some cache architectures, and equally possible the subtraction is effectively free on some compiler/instruction set/code path combinations.
The only way to tell is to benchmark realistic code.