Implementing a 2d array for an object - c++

Creating a crossword puzzle generator. The grid size is chosen by input and the grid will be generated. I'd like the grid to be an object with rows and columns but also a 2d array which will allow me to divide the grid into smaller sections for randomising between blank and numbered squares. I am not sure where to implement it.
It has to be a 2d array as I will do dividing and inverting the layout.
Here is my Grid class with some methods. (And the rest)
class Grid
{
int rows; //x
int columns; //y
Square field;
public:
void SetXY(int x, int y)
{
rows = x;
columns = y;
return;
}
public:
void DisplaySize()
{
cout << "Rows = ", rows, "Columns = ", columns;
}
};

The simplest way to implement a 2D array is to use a std::array<std::array<>> or std::vector<std::vector<>> - depending on whether it needs to be a static or dynamically sized array.
But, you can also just use a one dimensional std::array or std::vector and then just get the second dimension by indexing like row*size_of_row+column.

Related

Vector dot product in Microsoft SEAL with CKKS

I am currently trying to implement matrix multiplication methods using the Microsoft SEAL library. I have created a vector<vector<double>> as input matrix and encoded it with CKKSEncoder. However the encoder packs an entire vector into a single Plaintext so I just have a vector<Plaintext> which makes me lose the 2D structure (and then of course I'll have a vector<Ciphertext> after encryption). Having a 1D vector allows me to access only the rows entirely but not the columns.
I managed to transpose the matrices before encoding. This allowed me to multiply component-wise the rows of the first matrix and columns (rows in transposed form) of the second matrix but I am unable to sum the elements of the resulting vector together since it's packed into a single Ciphertext. I just need to figure out how to make the vector dot product work in SEAL to perform matrix multiplication. Am I missing something or is my method wrong?
It has been suggested by KyoohyungHan in the issue: https://github.com/microsoft/SEAL/issues/138 that it is possible to solve the problem with rotations by rotating the output vector and summing it up repeatedly.
For example:
// my_output_vector is the Ciphertext output
vector<Ciphertext> rotations_output(my_output_vector.size());
for(int steps = 0; steps < my_output_vector.size(); steps++)
{
evaluator.rotate_vector(my_output_vector, steps, galois_keys, rotations_output[steps]);
}
Ciphertext sum_output;
evaluator.add_many(rotations_output, sum_output);
vector of vectors is not the same as an array of arrays (2D, matrix).
While one-dimentional vector<double>.data() points to contiguous memory space (e.g., you can do memcpy on that), each of "subvectors" allocates own, separate memory buffer. Therefore vector<vector<double>>.data() makes no sense and cannot be used as a matrix.
In C++, two-dimensional array array2D[W][H] is stored in memory identically to array[W*H]. Therefore both can be processed by the same routines (when it makes sense). Consider the following example:
void fill_array(double *array, size_t size, double value) {
for (size_t i = 0; i < size; ++i) {
array[i] = value;
}
}
int main(int argc, char *argv[])
{
constexpr size_t W = 10;
constexpr size_t H = 5;
double matrix[W][H];
// using 2D array as 1D to fill all elements with 5.
fill_array(&matrix[0][0], W * H, 5);
for (const auto &row: matrix) {
for (const auto v : row) {
cout << v << '\t';
}
cout << '\n';
}
return 0;
}
In the above example, you can substitute double matrix[W][H]; with vector<double> matrix(W * H); and feed matrix.data() into fill_array(). However, you cannot declare vector(W) of vector(H).
P.S. There are plenty of C++ implementations of math vector and matrix. You can use one of those if you don't want to deal with C-style arrays.

c++ Sudokou Grid initialisation

So I'm very new to c++, studying it at present and have a piece of work to do that's stumping me. You guys are the first port of call.
I need to make what is essentially a 2d array of objects. The header file includes Cell objects for rows, columns and blocks. The idea that I have a 9x9 array of objects, with relevant pointers based on column, row and internal 3x3 block therein. What I'm stuck on is that the below line fills out the 9x9 but how am I pointing to each Cell?
Or is that in something separate and this is all I need to do for just setting up that grid??
void SudokuPuzzle::InitialiseGrid()
{
for (int row = 0; row < 9; row++)
{
for (int column = 0; column < 9; column++)
{
m_gridRows[row].SetCell(column, new SudokuSquare());
// have the cell point to both it's position in the column and block
}
}
}
Maybe try to create the 2d array of the Type "SudokuSquare".
SudokuSquare sSquare [9][9];
So you can acces any object by
sSquare[row][column];
If your array is fixed size e.g. 3x3 just use std::array:
#include <array>
using std::array;
int main()
{
array<array<int, 3>, 3> sudoku_squares{};
sudoku_squares[0][1] = 1; // sets cell at first row, second column to 1
return 0;
}
In your case you can store 9 of those 3x3 arrays in another array or just use 9x9 array and you don't need to use any pointers. I used int in my example but you can store SudokuSquare exactly the same way.

Sorting an array of structs in C++

I'm using a particle physics library written in c++ for a game.
In order to draw the particles I must get an array of all their positions like so..
b2Vec2* particlePositionBuffer = world->GetParticlePositionBuffer();
This returns an array of b2Vec2 objects (which represent 2 dimensional vectors in the physics engine).
Also I can get and set their colour using
b2ParticleColor* particleColourBuffer = world->GetParticleColorBuffer();
I would like to get the 10% of the particles with the highest Y values (and then change their colour)
My idea is..
1. Make an array of structs the same size as the particlePositionBuffer array, the struct just contains an int (the particles index in the particlePositionBuffer array) and a float (the particles y position)
2.Then I sort the array by the y position.
3.Then I use the int in the struct from the top 10% of structs in my struct array to do stuff to their colour in the particleColourBuffer array.
Could someone show me how to sort and array of structs like that in c++ ?
Also do you think this is a decent way of going about this? I only need to do it once (not every frame)
Following may help:
// Functor to compare indices according to Y value.
struct comp
{
explicit comp(b2Vec2* particlePositionBuffer) :
particlePositionBuffer(particlePositionBuffer)
{}
operator (int lhs, int rhs) const
{
// How do you get Y coord ?
// note that I do rhs < lhs to have higher value first.
return particlePositionBuffer[rhs].getY() < particlePositionBuffer[lhs].getY();
}
b2Vec2* particlePositionBuffer;
};
void foo()
{
const std::size_t size = world->GetParticleCount(); // How do you get Count ?
const std::size_t subsize = size / 10; // check for not zero ?
std::vector<std::size_t> indices(size);
for (std::size_t i = 0; i != size; ++i) {
indices[i] = i;
}
std::nth_element(indices.begin(), indices.begin() + subsize, indices.end(),
comp(world->GetParticlePositionBuffer()));
b2ParticleColor* particleColourBuffer = world->GetParticleColorBuffer();
for (std::size_t i = 0; i != subsize; ++i) {
changeColor(particleColourBuffer[i])
}
}
If your particle count is low, it won't matter much either way, and sorting them all first with a simple stl sort routine would be fine.
If the number were large though, I'd create a binary search tree whose maximum size was 10% of the number of your particles. Then I'd maintain the minY actually stored in the tree for quick rejection purposes. Then this algorithm should do it:
Walk through your original array and add items to the tree until it is full (10%)
Update your minY
For remaining items in original array
If item.y is less than minY, go to next item (quick rejection)
Otherwise
Remove the currently smallest Y value from the tree
Add the larger Y item to the tree
Update MinY
A binary search tree has a nice advantage of quick insert, quick search, and maintained ordering. If you want to be FAST, this is better than a complete sort on the entire array.

Tilemap array of unknown size

I want the users to pick there map size so I do not know the size of the map at run time. I have been looking around how I can implement this with little success. Closest to something that is working is with the vector variant but while it runs it still does not work properly.
I want a 3 dimensional array so in my header i declare the tilemap like this.
std::vector<std::vector<std::vector<Tile>>> tileMap;
and test it in the class like this:
World::World(int width, int height, int depth)
{
tileMap.resize(width);
tileMap[0].resize(height);
tileMap[0][0].resize(depth);
tileMap.resize(width);
for (int i = 0;i<width;i++)
{
tileMap[i].resize(height);
}
for (int y = 0; y < height;y++)
{
for (int x = 0; x < width; x++)
{
tileMap[x,y].resize(depth);
}
}
std::cout << sizeof tileMap / sizeof tileMap[0][0][0] << std::endl;
}
I am aware that not all the dimensions of the array are resized properly but the final line just outputs "0".
Is there i better way to create my tilemap of unknown size? I need a lot of sizes like 64*64, 256*256, 64*1024, etc (the z levels will be determined after generating the level). so creating an array for each size seems inefficient. But maybe there is a better way of declaring my array or i am doing something wrong somewhere.
You want tileMap.size() * tileMap[0].size() * tileMap[0][0].size() to get the number of tiles.

swapping an inner and outer vector

I have a vector of vector of myObjects defined, creating essentially a 2D array. I would like to transpose this array such that rows become columns and columns become rows. Obviously I could do this in a double for-loop, but this seems massively inelegant and will be pretty slow. I was wondering if there's something clever in C++ or the STL that would let me swap the inner and outer vectors around quickly and efficiently, rather than writing...
for (int iRow = 0; iRow < nRows; ++iRow)
{
for (int iCol = 0; iCol < nCols; ++iCol)
{
myNew2DArray[iCol][iRow] = myOriginal2DArray[iRow][iCol];
}
}
Alternatively, you can store the matrix in a vector and have a flag that specifies whether the matrix is transposed or not. Then you simply calculate the index. Here is an example:
class Matrix {
private:
std::vector<int> matrix;
bool isTransposed = false;
int width, height;
public:
// ...
int getElement(int x, int y)
{
int w = width;
int h = height;
if(isTransposed) {
int z = x;
x = y;
y = x;
z = w;
w = h;
h = z;
}
return matrix[y * width + x];
}
// ...
};
This will reduce the cost of transposing the matrix, but increases the cost of actually accessing the elements.
My suggestion would be to make a class called Matrix that contains the matrix that you are talking about. Give the class a function transpose() that toggles a state flag for the state "transposed". Then, overload the [] operator to follow mwd's suggestion of inverting the indeces when the matrix is in the transposed state.
What you've coded already is pretty much the easiest way. Really you don't need a vector of vectors. You can just append each new 'row' to a single vector. Then what would have been element matrix[i][j] in your original vector of vectors is now matrix[(i*n)+j], when n is the 'width' of your matrix. The fiddly part is coming up with the algorithm to perform the transpose. I'm not saying this way is any better, but it's an alternative route, and what you've got already is fine.
Your best bet is using the Eigen matrix library, which stores the transposedness property in a parameter of the matrix class. If that is not an option, google for one of the numerous matrix transpose algorithms.