I have to create a three-dimensional array using class A as element ,class A is defined like below, should I use vector<vector<vector<A> > > or boost::multi_array? Which one is better?
struct C
{
int C_1;
short C_2;
};
class B
{
public:
bool B_1;
vector<C> C_;
};
class A
{
public:
bool A_1;
B B_[6];
};
If you know the size of all three dimensions at the time, that you write your code, and if you don't need checking for array bounds, then just use traditional arrays:
const int N1 = ...
const int N2 = ...
const int N3 = ...
A a[N1][N2][N3]
If the array dimensions can onlybe determined at run time, but remain constant after program initialization, and if array usage is distributed uniformly, then boost::multi_array is your friend. However, if a lot of dynamic extension is going on at runtime, and/or if array sizes are not uniform (for example, you need A[0][0][0...99] but only A[2][3][0...3]), then the nested vector is likely the best solution. In the case of non-uniform sizes, put the dimension, whose size variies the most, as last dimension. Also, in the nested vector solution, it is generally a good idea to put small dimensions first.
The main concern that I would have about using vector<vector<vector<A> > > would be making sure that the second- and third-level vectors all have the same length like they would in a traditional 3D array, since there would be nothing in the data type to enforce that. I'm not terribly familiar with boost::multi_array, but it looks like this isn't an issue there - you can resize() the whole array, but unless I'm mistaken you can't accidentally remove an item from the third row and leave it a different size than all of the other rows (for example).
So assuming concerns like file size and compile time aren't much of an issue, I would think you'd want boost::multi_array. If those things are an issue, you might want to consider using a plain-old 3D array, since that should beat either of the other two options hands-down in those areas.
Related
I am currently working on a big project involving repast_hpc and mpi. I wanted to implement a two dimensional shared (across processes) array, because repast_hpc itself does not seem to come with that. For that I need an array member of a class. However I do not know the size of the array at compile time.
I need to be able to access and change the values in constant time. The code given below is my current header file, where the problem is located. How can I get a array member like the values in array in c++11?
template <typename Value>
class SharedValueField {
private:
Value[][] values;
std::queue<ValueChangePackage<Value>> changes;
public:
void initializeValueChange(int x, int y, Value value);
Value getValue(int x, int y);
void update();
};
All help appreciated. Thanks!
Tritos
I already tried using std::array. That has the same problems. I cant use std::vector, because they dont allow for constnt-time random element value manipulation.
Using ‚std::vector‘ works after all. As explained by many people in the comments, only changing the size of the vector has time-complexity in O(n). I only need to reassign elements, which works fine.
An external library gives me a raw pointer of doubles that I want to map to an Eigen type. The raw array is logically a big ordered collection of small dense fixed-size matrices, all of the same size. The main issue is that the small dense matrices may be in row-major or column-major ordering and I want to accommodate them both.
My current approach is as follows. Note that all the entries of a small fixed-size block (in the array of blocks) need to be contiguous in memory.
template<int bs, class Mattype>
void block_operation(double *const vals, const int numblocks)
{
Eigen::Map<Mattype> mappedvals(vals,
Mattype::IsRowMajor ? numblocks*bs : bs,
Mattype::IsRowMajor ? bs : numblocks*bs
);
for(int i = 0; i < numblocks; i++)
if(Mattype::isRowMajor)
mappedvals.template block<bs,bs>(i*bs,0) = block_operation_rowmajor(mappedvals);
else
mappedvals.template block<bs,bs>(0,i*bs) = block_operation_colmajor(mappedvals);
}
The calling function first figures out the Mattype (out of 2 options) and then calls the above function with the correct template parameter.
Thus all my algorithms need to be written twice and my code is interspersed with these layout checks. Is there a way to do this in a layout-agnostic way? Keep in mind that this code needs to be as fast as possible.
Ideally, I would Map the data just once and use it for all the operations needed. However, the only solution I could come up with was invoking the Map constructor once for every small block, whenever I need to access the block.
template<int bs, StorageOptions layout>
inline Map<Matrix<double,bs,bs,layout>> extractBlock(double *const vals,
const int bindex)
{
return Map<Matrix<double,bs,bs,layout>>(vals+bindex*bs*bs);
}
Would this function be optimized away to nothing (by a modern compiler like GCC 7.3 or Intel 2017 under -std=c++14 -O3), or would I be paying a small penalty every time I invoke this function (once for each block, and there are a LOT of small blocks)? Is there a better way to do this?
Your extractBlock is fine, a simpler but somewhat uglier solution is to use a reinterpret cast at the start of block_operation:
using BlockType = Matrix<double,bs,bs,layout|DontAlign>;
BlockType* blocks = reinterpret_cast<BlockType*>(vals);
for(int i...)
block[i] = ...;
This will work for fixed sizes matrices only. Also note the DontAlign which is important unless you can guaranty that vals is aligned on a 16 or even 32 bytes depending on the presence of AVX and bs.... so just use DontAlign!
I need to check if structures were changed, for this i have static assert implemented through template technique. But for now i only have checked sizeof, but one can add something to a structure without changing sizeof.
How can i calculate sum of sizeofs of members?
struct A
{
int i;
bool b;
};
I need __sizeof(A) to be equal to 3 that is sizeof(A::i) + sizeof(A::b).
I need it to be done for big lot of structures in my project, and structures must be padded as it supposed to give the best performance.
I have been reading up on C++ lately, especially STL, and I decided to do the Knights Tour problem again. I'm thinking about the best way to implement this, and I'm looking for some help.
Just for fun and practice, I thought I'd start with a "Piece" base class, which a "Knight" class can inherit from. I want to do this so I later can try adding other pieces(even though most of the pieces can't walk over the whole board and complete the problem).
So the "piece class" will need some sort of container to store the coordinates of the piece on the board and the number of moves it has made in that specific step.
I'm thinking I need a linked list with 64 (8 * 8) places to do this most efficiently, containing x,y and moves.
Looking at the STL containers, I can't find anything except map that will hold more than one type.
What can I do to store the coordinate pair and an int for the number of moves in one container? Are there more efficient ways of doing this than using vector, list or map? Do I need a custom container?
Thanks!
You can use
struct CellInfo
{
int x, y, move_count;
}
And store it in std::vector for constant access.
Apart from STL and encapsulation, a very efficient way is to use arrays:
pair<int, int> piece_pos[N];
int piece_move[N];
This avoids the overhead of memory leakage and is faster than dynamic allocation.
If you stell want to use STL, then:
vector<pair<int, int> > piece_pos(N);
vector<int> piece(N);
The C++ STL now has static arrays as well. If you want to store the number of times a given x,y coordinate has been moved to, you can create an array of arrays like the following:
using container_type = std::array<std::array<int, 8>, 8>;
// ...
container_type c;
int moves = c[x][y]; // constant-time access.
If you don't need to look moves up based on x,y, and just want the data stored efficiently, use a flat array of size 8x8 = 64.
If your compiler is out of date, consider using std::vector instead.
I am working on some core audio code and have a problem that could be solved by a variable array in a struct--a la Flexible Array Members. In doing a bit of looking around, I see that there is a lot of dialogue about the portability and viability of Flexible Member Arrays.
From what I understand, Objective-C is C99 compliant. For this reason, I think Flexible Array Members should be a fine solution. I also see that Flexible Array Members are not a good idea in C++.
What to do in Objective-C++? Technically, I won't use it in Objective-C++. I am writing callbacks that are C and C++ based... That seems like a point against.
Anyway, can I (should I) do it? If not, is there another technique with the same results?
You can always just declare a trailing array of size 1. In the worst case here, you waste a pretty small amount of memory, and it is very slightly more complicated to compute the right size for malloc.
don't bother. it's not compatible. it is messy and error prone. c++ had solutions which are managed more easily long before this feature existed. what are you tacking onto the end of your struct? normally, you'll just use something like a std::vector, std::array, or fixed size array.
UPDATE
I want to have a list of note start times (uint64_t) and iterate through them to see which, if any, is playing. i was going to add a count var to the struct to track how many items are in the flexible array.
ok, then a fixed size array should be fine if you have fixed polyphony. you will not need more than one such array in most iOS synths. of course, 'upcoming note' array sizes could vary based on the app synth? sampler? sequencer? live input?
template <size_t NumNotes_>
class t_note_start_times {
public:
static const size_t NumNotes = NumNotes_;
typedef uint64_t t_timestamp;
/*...*/
const t_timestamp& timestampAt(const size_t& idx) const {
assert(this->d_numFutureNotes <= NumNotes);
assert(idx < NumNotes);
assert(idx < this->d_numFutureNotes);
return this->d_startTimes[idx];
}
private:
t_timestamp d_presentTime;
size_t d_numFutureNotes; // presumably, this will be the number of active notes,
// and values will be compacted to [0...d_numFutureNotes)
t_timestamp d_startTimes[NumNotes];
};
// in use
const size_t Polyphony = 16;
t_note_start_times<Polyphony> startTimes;
startTimes.addNoteAtTime(noteTimestamp); // defined in the '...' ;)
startTimes.timestampAt(0);
if you need a dynamically sized array which could be very large, then use a vector. if you need only one instance of this and the max polyphony is (say) 64, then just use this.