I am generating hadamard matrices where for any 2d matrix "M" the next matrix is:
M, M
M,-M
e.g.
Matrix starts with a 1x1 matrix with value "1", such that:
1 (x) 1, 1 = 1, 1
1,-1 1,-1
1, 1 (x) 1, 1 = 1, 1, 1, 1
1,-1 1,-1 1,-1, 1,-1
1, 1,-1,-1
1,-1,-1, 1
And so on... see here
So I have a type:
typedef std::vector<std::vector<char>> matrix_t;
In my constructor I set the matrix to the start value:
hadamard::hadamard() :
m_matrix{{1}}
{
}
So to make the next matrix I decided I could copy the rows (a repeat copy) and then copy the complete matrix (again a repeat copy):
void hadamard::generate_next(matrix_t& matrix, size_t size)
{
if (matrix.size() < size)
{
hadamard::print_matrix(matrix, "before");
// Copy the matrix into 4: M1 | M2
// ---+---
// M3 | M4
// For each inner vector - copy it (double up)
for(auto& row : matrix)
{
// Double up the row
row.insert(row.end(), row.begin(), row.end());
}
// For the outer vector - copy it (double up)
matrix.insert(matrix.end(), matrix.begin(), matrix.end());
// Invert chars in M4 (see diagram above)
TODO
hadamard::print_matrix(matrix, "after");
// Ok, feeling brave, now call recursively...
generate_next(matrix, size);
}
}
Just for completeness here is my print function:
static void print_matrix(matrix_t& matrix, const char * title)
{
printf("%s\r\n", title);
printf("Dimensions - rows: %d, cols: %d\r\n", matrix.size(), matrix[0].size());
int row = 1;
for(auto& line : matrix)
{
printf("NEW LINE\r\n");
int col = 1;
for (auto& item : line)
{
printf("item(%d, %d): %d\r\n", row, col, item);
++col;
}
++row;
}
}
The output I get is like this:
before
Dimensions - rows: 1, cols: 1
NEW LINE
item(1, 1): 1
after
Dimensions - rows: 2, cols: 2
NEW LINE
item(1, 1): 1
item(1, 2): 1
NEW LINE
<HERE SHOULD BE A COPY OF THE PREVIOUS "LINE">
You can see from the output that the inner copy works ok - I guess this is because I am working on std::vector so the inner data is chars.
But the outer copy does not work, I think this is something this vector being a "vector of vectors" (the full type is std::vector<std::vector<char>>
).
So basically the line:
// For the outer vector - copy it (double up)
matrix.insert(matrix.end(), matrix.begin(), matrix.end());
does appear to double the size of matrix
but it does not copy the data.
Why does it not copy the data? - is it because a deep copy is needed? Also, what is an efficient way to do this?
In the mean time I am going to manually copy the data across from each row... just to prove to myself that I can do it!
UPDATE
Ok, I "think" I have a really simple fix.... may not be the best way?
for(auto& row : matrix)
{
// Double up the row
row.insert(row.end(), row.begin(), row.end());
// Now copy the row down as well
matrix.insert(matrix.end(), row);
}
But my previous questions still stand!
UPDATE 2
No, the last code change "seemed" to work, at least for the first iteration... but once I start re-cursing through it breaks down... I have updated the "recursion" so it re-curses, I had not written that code properly... now I get the output:
HADAMARD MATRIX GENERATOR
Generating HM for index 2 - dimensions: 4x4, size: 16
before
Dimensions - rows: 1, cols: 1
1
after
Dimensions - rows: 2, cols: 2
1 1
1 1
before
Dimensions - rows: 2, cols: 2
1 1
1 1
after
Dimensions - rows: 4, cols: 4
1 1 1 1
1 1
1 1 1 1
before
Dimensions - rows: 4, cols: 4
1 1 1 1
1 1
1 1 1 1
after
Dimensions - rows: 8, cols: 8
1 1 1 1 1 1 1 1
1 1
1 1 1 1
1 1 1 1 1 1 1 1
So, its not going well at all! - I am thinking the concatenation of my vectors is all wrong?...