Sorting a table C++ - c++

I have a table of numbers that look like this:
2 8 4 0
3 1 0 9
1 2 3 4
5 4 14 2
I put all the numbers in an array { 2,8,4,0,3,1... }. Is there a way to sort it by the first column only using a 1D array so that it ends up like this:
1 2 3 4
2 8 4 0
3 1 0 9
5 4 14 2
I know there's a way of doing it with a 2D array, but, assuming I know the number of columns, is it possible with only a 1D array?

I'd create an array of indexes into your data, and then sort those indexes; this will save a decent number of the copies.
Your sort would then examine the value of the number at the given index.
ie for your example - indexes would be 1,2,3,4
and then sorted would read 3,1,2,4
edit: this was 1 based; the code 0 based. Makes no difference.
Essentially converting your 1d array into 2. Since the bulk of your data is still contiguous (especially for large numbers of columns) reading should still be fast.
Example code:
std::vector<int> getSortedIndexes(std::vector<int> data, int size) {
int count = data.size() / size;
std::vector<int> indexes(count);
// fill in indexes from 0 to "count" since that's the size of our vector
std::iota(indexes.begin(), indexes.end(), 0);
// don't write your own sorting implementation .... really; don't.
std::sort(indexes.begin(), indexes.end(), [data, size](int indexA, int indexB) {
return data[indexA*size] < data[indexB*size];
});
return indexes;
}

For arrays of non-user defined types it is easy to do the task using the standard C function qsort.
Here is a demonstrative program.
#include <iostream>
#include <cstdlib>
int cmp( const void *a, const void *b )
{
const int *left = static_cast<const int *>( a );
const int *right = static_cast<const int *>( b );
return ( *right < *left ) - ( *left < *right );
}
int main()
{
const size_t N = 4;
int a[N * N] =
{
2, 8, 4, 0, 3, 1, 0, 9, 1, 2, 3, 4, 5, 4, 14, 2
};
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
std::cout << a[N * i + j] << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
std::qsort( a, N, sizeof( int[N] ), cmp );
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
std::cout << a[N * i + j] << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
}
The program output is
2 8 4 0
3 1 0 9
1 2 3 4
5 4 14 2
1 2 3 4
2 8 4 0
3 1 0 9
5 4 14 2
So all you need is to write the function
int cmp( const void *a, const void *b )
{
const int *left = static_cast<const int *>( a );
const int *right = static_cast<const int *>( b );
return ( *right < *left ) - ( *left < *right );
}
and add just one line in your program
std::qsort( a, N, sizeof( int[N] ), cmp );

You can use bubblesort:
void sort_by_name(int* ValueArray, int NrOfValues, int RowWidth)
{
int CycleCount = NrOfValues / RowWidth;
int temp;
(int j = 0; j < CycleCount ; j++)
{
for (int i = 1; i < (CycleCount - j); i++)
{
if(ValueArray[((i-1)*RowWidth)] > ValueArray[(i*RowWidth)])
{
for(int k = 0; k<RowWidth; k++)
{
temp = ValueArray[(i*RowWidth)+k]
ValueArray[(i*RowWidth)+k] = ValueArray[((i-1)*RowWidth)+k];
ValueArray[((i-1)*RowWidth)+k] = temp;
}
}
}
}
}
keep in mind that simply making your array 2D will be a MUCH BETTER solution
edit: variable naming

Related

Multiplying two matrix in a different way - can't figure it out how to do it

As a homework, I have a problem which sounds like this:
We have a n*n square matrix. It is called 'subdiagonal'
if all the elements above the main diagonal are null.
a) Copy the useful elements (the ones which are not null, so basically all the elements
from the main diagonal and below) to an array. (I've done that)
b) Write an algorithm which takes two subdiagonal matrix A, B as an input.
Those are transformed into arrays V_a and V_b with the algorithm from a),
then they calculate C = A*B only using only V_a and V_b
e.g.
Let's say A =
1 0 0 0 0
2 3 0 0 0
4 1 3 0 0
1 9 0 2 0
1 0 1 2 2
B =
2 0 0 0 0
1 1 0 0 0
0 1 2 0 0
1 1 2 3 0
2 0 0 1 2
after this input, V_a = 1,2,3,4,1,3,1,9,0,2,1,0,1,2,2; V_b = 2,1,1,0,1,2,1,1,2,3,2,0,0,1,2
and the product V_c will be 2,7,3,9,4,6,13,11,4,6,8,3,6,8,4
so the matrix will look like
2 0 0 0 0
7 3 0 0 0
9 4 6 0 0
13 11 4 6 0
8 3 6 8 4
Here's the code that I've been working on for a while:
#include <iostream>
#include <algorithm>
void read(int& a, int**& matrix)
{
std::cin >> a;
matrix = new int*[a];
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
matrix[i] = new int[a];
}
}
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
std::cin >> matrix[i][j];
}
}
}
void showMatrix(int a, int** matrix)
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < a; j++)
{
std::cout << matrix[i][j] << " ";
}
std::cout << std::endl;
}
}
void showArray(int a, int* array)
{
for (int i = 0; i < a; i++)
{
std::cout << array[i] << " ";
}
}
void createArray(int a, int& arrayLength, int** matrix, int*& array)
{
int nrDeElemente = a*a - (a * (a - 1)) / 2;
array = new int[nrDeElemente+1];
arrayLength = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < i+1; j++)
{
array[arrayLength++] = matrix[i][j];
}
}
}
int* multiplyArrays(int a, int arrayLength, int* array1, int* array2)
{
int* array3 = new int[arrayLength + 1];
for (int i = 0; i < a; i++)
{
array3[i] = 0;
}
int t = 1;
for (int i = 0; i < arrayLength; ++i)
{
for (int j = 0; j < t; ++j)
{
for (int p = j; p < a; p++)
{
array3[i] += array1[j] * array2[p];
}
}
++t;
}
return array3;
}
int main()
{
int **matrix1, **matrix2;
int *array1, *array2, *multiplyResult;
int a, arrayLength;
read(a, matrix1);
read(a, matrix2);
createArray(a, arrayLength, matrix1, array1);
createArray(a, arrayLength, matrix2, array2);
multiplyResult = multiplyArrays(a, arrayLength, array1, array2);
showArray(arrayLength, multiplyResult);
}
I've done a), but I don't know how to do b)
I think I understood it (after many hours of trials) conceptually, but I don't really know how to implement it.
I need 3 for loops, as such:
->the most outer one has to be responsible for the position we calculate on the new array
->the next one has to choose which elements from the second array will be multiplied. (choose the multiplier) That's one of
the loops I don't know how to implement. It somehow has to stop when the line (from the matrix) ended and start where it stopped + 1 element.
->the most inner one has to choose the second term of the multiplication (the multiplicand).
I also don't know how I should implement this one. It should choose as many elements as there multipliers are and also, the looping is quite strange (because I need to select all the elements from the same row every time).
Can anybody help me solve point b and also explain their thinking?
I struggled a lot and I really feel like I need help.
BTW the 3 for loops from multiplyArrays make no sense, you can just write something else instead of them. Those 3 for loops are basically the only things that my program needs (I think).
Thanks :)
Matrix multiplication C = A*B is defined by C(i,j) = sum_k A(i,k)*B(k,j). The matrix A has structural nonzeros where i >= k, and B, where k >= j. Thus it suffices to iterate
(outer loop) i from 0 to n-1
(middle) j from 0 to i
(inner) k from j to i.
The other piece is turning coordinates (i,j) into an offset with respect to the 1D storage format. The number of structural nonzeros in the first i rows is given by the ith triangular number, (i+1)*i/2. Hence the jth element in this row is at (zero-based) index (i+1)*i/2 + j. You or your compiler can strength-reduce the multiplication.
To multiply matrices requires to find where a row start in array, for example row[2] starts at index 3 in array as highlighted below,
1 0 0 0 0
2 3 0 0 0
4 1 3 0 0 => row[2]
1 9 0 2 0
1 0 1 2 2
[1, 2, 3, 4, 1, 3, 1, 9, 0, 2, 1, 0, 1, 2, 2]
Any row can be found if we know how may elements are present before it, like in above example if we know that three elements are present before row[2] then we can locate row[2] easily.
To find number of elements presents before each row requires to calculated an auxiliary array of size equals to number of rows, but to do that let's first see matrix again,
As you can see each row contains element equal to the index + 1 of row,
1 element count = index + 1 = 0 + 1 = 1
2 3 = 1 + 1 = 2
4 1 3 = 2 + 1 = 3
1 9 0 2 ..
1 0 1 2 2 ..
It means our auxiliary array would be,
auxiliary array = [0, 1, 2, 3, 4] but how ?
As we know there are no element before row[0] that's why auxiliaryArray[0] = 0 then elements before row[1] is only one element which can be found by index of previous row that is previous row index + 1 => 0 + 1 as showed above auxiliaryArray[1] = 1 and similar for all rows,
But it is not done! current state of auxiliary array is only having information about number of elements present in immediate previous row but not in all previous rows, and to do so we have to calculate sum of all previous rows and that is called partial sum and it will be done as follows,
row[0] = row[0]
row[1] = row[0] + row[1]
row[2] = row[1] + row[2]
..
..
and final result,
auxiliary array = [0, 1, 3, 6, 10]
So as you can see number of elements before row[2] = auxiliaryArray[2] = 3
By using above auxiliary array you can locate any row and if you get first element of row you can find all col elements.
Next point to understand is how many elements you have to multiply in each row and that is again number of elements to multiply = index + 1 as you see above in matrix row[0] only have one element to multiple index + 1 => 0 + 1 and same rule apply for each row.
Last point to consider is, when row is multiplied with col of other matrix it doesn't start always with row[0] of other matrix as you can see below otherMatrix[0][1] is outside of left diagonal of other matrix,
2 0 0 0 0
1 1 0 0 0
0 1 2 0 0
1 1 2 3 0
2 0 0 1 2
Finally we are done!
#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
using std::cout;
void printMatrixArray(std::size_t rowSize, const std::vector<int>& matArray){
std::size_t elementCount = 1;
std::vector<int>::const_iterator it = matArray.cbegin();
for(std::size_t row = 0; row < rowSize; ++row){
std::copy(it, it + elementCount, std::ostream_iterator<int>(cout, "\t"));
cout<< '\n';
it += elementCount;
++elementCount;
}
}
std::vector<int> leftDiagonalBottomMatrix(const std::vector<std::vector<int>>& mat){
std::vector<int> res;
res.reserve(((1 + mat.size()) * mat.size()) / 2);
std::vector<int>::size_type elementCount = 1;
for(const std::vector<int>& row : mat){
for(std::vector<int>::const_iterator it = row.cbegin(), endIt = row.cbegin() + elementCount; endIt != it; ++it){
res.push_back(*it);
}
++elementCount;
}
return res;
}
std::vector<int> multiplyMatrixArrays(const std::vector<int>& mat1Arr, const std::vector<int>& mat2Arr,
std::vector<int>::size_type rowSize){
std::vector<int> auxiliaryArray(rowSize);
auxiliaryArray.front() = 0;
std::iota(auxiliaryArray.begin() + 1, auxiliaryArray.end(), 1);
std::partial_sum(auxiliaryArray.cbegin(), auxiliaryArray.cend(), auxiliaryArray.begin());
std::vector<int> res;
res.reserve(mat1Arr.size());
for(std::vector<int>::size_type row = 0; row < rowSize; ++row){
for(std::vector<int>::size_type col = 0; col <= row; ++col){
int val = 0;
for(std::vector<int>::size_type ele = col, elementCount = row + 1; ele < elementCount; ++ele){
val += mat1Arr[auxiliaryArray[row] + ele] * mat2Arr[auxiliaryArray[ele] + col];
}
res.push_back(val);
}
}
return res;
}
std::vector<int> matrixMultiply(const std::vector<std::vector<int>>& mat1, const std::vector<std::vector<int>>& mat2){
return multiplyMatrixArrays(leftDiagonalBottomMatrix(mat1), leftDiagonalBottomMatrix(mat2), mat1.size());
}
int main(){
std::vector<std::vector<int>> mat1{{1, 0, 0, 0, 0}, {2, 3, 0, 0, 0}, {4, 1, 3, 0, 0}, {1, 9, 0, 2, 0},
{1, 0, 1, 2, 2}};
std::vector<std::vector<int>> mat2{{2, 0, 0, 0, 0}, {1, 1, 0, 0, 0}, {0, 1, 2, 0, 0}, {1, 1, 2, 3, 0},
{2, 0, 0, 1, 2}};
printMatrixArray(mat1.size(), matrixMultiply(mat1, mat2));
}
Output:
2
7 3
9 4 6
13 11 4 6
8 3 6 8 4
Output does not print elements above the left diagonal of matrix!

Optimized (memory-wise) implementation of full graph in C++

I need to implement Watts-Strogatz algorithm and I'm running into some problems with creating a full graph. The way I'm implemeting it, it takes up so much memory and I need to work on big systems so that is a problem.
I'm creating a matrix called lattice for my n nodes with their n - 1 = k neighbours. For eg. let's say n = 7. My lattice will look like:
1 6 2 5 3 4
2 0 3 6 4 5
3 1 4 0 5 6
4 2 5 1 6 0
5 3 6 2 0 1
6 4 0 3 1 2
0 5 1 4 2 3
And now the code to create it.
This is main.cpp:
#include "lattice.h"
#include <vector>
int main() {
/*
* initial parameters
*/
int n = 7; //number of agents MUST BE ODD
int k = 6; //number of agents with whom we wire; N - 1 for full graph
// NEEDS TO BE EVEN
int** lattice = new int* [n];
/*
* creating ring lattice
*/
for (int i = 0; i < n; i++) {
lattice[i] = new int [k];
}
createRingLattice (n, k, lattice);
delete[](lattice);
std::cout << std::endl;
return 0;
}
And this is the function createRingLattice:
void createRingLattice (int n, int k, int** lattice) {
/*
* setting up ring lattice
*/
//table of the nearest neighbours
//next iN previous iP
int* iP = new int [n];
int* iN = new int [n];
for (int i = 0; i < n; i++) {
iP[i] = i - 1;
iN[i] = i + 1;
}
//boundary conditions
iP[0] = n - 1;
iN[n - 1] = 0;
for (int i = 0; i < n; i++) {
int countP = 0;
int countN = 0;
for (int j = 0; j < k; j++) {
if (j % 2 == 0) {
if (i + countN > n - 1) {
lattice[i][j] = iN[i + countN - n];
} else {
lattice[i][j] = iN[i + countN];
}
countN++;
}
if (j % 2 == 1 ) {
if (i - countP < 0) {
lattice[i][j] = iP[n + i - countP];
} else {
lattice[i][j] = iP[i - countP];
}
countP++;
}
}
}
delete[](iN);
delete[](iP);
}
First question:
Is there a way to implement this with much less memory usage?
Second question:
I've seen people implementing graphs with adjacency list (this one for example) but I'm wondering if it's acctually more optimized than my implemantation? It does use pointers as well and I'm not the expert so it's hard for me to determine whether it's better when it comes to memory usage.
Note: I'm not concerned about speed at the moment.

How to iterate through only specific column in c++?

I have a 2d array like this:
arr = [0 3 1 0
1 2 0 2
0 0 2 0
1 2 0 0]
My aim is don't iterate over a column once we find maximum number in it.
In the first iteration, max number is 3 in 2nd column, so don't go to second column in future iterations.
Similarly in my 2nd iteration, max number is 2 in 4th column (Because we dont go to 2nd column anymore).
This is what i tried:
#include <iostream>
using namespace std;
int main()
{
//Input 2d array
int arr[4][4];
//Take the input
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
cin>>arr[i][j];
}
//Index array to store index of maximum number column
int index[4] = {-1,-1,-1,-1}
//Array to store max number in each row
int max_arr[4] = {0,0,0,0};
for(int i=0; i<4; i++)
{
int max_num = -1;
for(int j=0; j<4; j++)
{
if(j!=index[0] && j!=index[1] && j!=index[2] && j!=index[3])
{
if(max_num<arr[i][j])
{
max_num = arr[i][j];
index[j] = j;
}
}
}
max_arr[i] = max_num;
}
return 0;
}
The best way to go about this is to simply evaluate the array by columns. This can be done with a little math. In your case, you use a 4x4 array. Start at index 0, add 4, add 4, add 4, then subtract 11 (bringing you to position 1). Add 4, add 4, add 4, subtract 11 (bringing you to position 2). Etc...
Here is the code I used, which works and is doable for any size array!
#include <iostream>
int main()
{
constexpr size_t ARR_ROWS = 4;
constexpr size_t ARR_COLS = 4;
constexpr size_t ARR_SIZE = ARR_ROWS * ARR_COLS;
int arr[ARR_SIZE] {
0, 3, 1, 0,
1, 2, 0, 2,
0, 0, 2, 0,
1, 2, 0, 0
};
// Store max values for columns
int cols_max[ARR_COLS] { -1, -1, -1, -1 };
// Start at index 0, then at 4 (3 times) to evaluate first
// column. Next, subtract 11 from current index (12) to get
// to index 1 (start of column 2). Add 4 (3 times) to
// evaluate second column. Next, subtract 11 from current
// index (13) to get to index 2 (start of column 3). Etc...
size_t cur_index = 0;
size_t cur_col = 0;
const size_t subtract_to_start_next_col = ARR_SIZE - (ARR_COLS + 1);
while (cur_index < ARR_SIZE)
{
// Max function for 'cols_max'
if (cols_max[cur_col] < arr[cur_index])
cols_max[cur_col] = arr[cur_index];
if ( // When index is at the column's end (besides last value)
(cur_index >= ARR_SIZE - ARR_COLS) &&
(cur_index <= ARR_SIZE - 2)
)
{
cur_index -= subtract_to_start_next_col;
cur_col++;
}
else if (cur_index == ARR_SIZE - 1)
{ // When index is last value, add 1 to break loop
cur_index++;
}
else
{ // Nothing special, just go to next value in column
cur_index += ARR_COLS;
}
}
// Print columns' max values (optional)...
for (size_t i = 0; i < ARR_COLS; ++i)
{
std::cout
<< "Max for column " << (i + 1) << ": " << cols_max[i]
<< std::endl;
}
}
Feel free to ask if you have any questions!
You need 3 loops, first for iterations, second for rows, third for columns. If you have found max at column let's say 0, then you should blacklist that column and so on.
#include <iostream>
int main()
{
int m[ 4 ][ 4 ] = { { 0, 3, 1, 0 } ,
{ 1, 2, 0, 2 } ,
{ 0, 0, 2, 0 } ,
{ 1, 2, 0, 0 } };
constexpr int max_number_of_itr { 4 };
bool blacklisted[4] { false };
for ( auto itr = 0; itr < max_number_of_itr; ++itr )
{
auto max { -1 };
auto max_col_idx { -1 };
for ( auto row = 0; row < 4; ++row )
{
for ( auto col = 0; col < 4; ++col )
{
if ( blacklisted[ col ] )
continue;
auto val = m[ row ][ col ];
if ( val > max )
{
max = val;
max_col_idx = col;
}
}
}
blacklisted[ max_col_idx ] = true;
std::cout << "max is " << max << " col " << max_col_idx << " ignored." << std::endl;
}
}
index[ j ] = j;
change this to
index[ i ] = j;

Dimension-independent loop over boost::multi_array?

Say I've got an N-dimensional boost::multi_array (of type int for simplicity), where N is known at compile time but can vary (i.e. is a non-type template parameter). Let's assume that all dimensions have equal size m.
typedef boost::multi_array<int, N> tDataArray;
boost::array<tDataArray::index, N> shape;
shape.fill(m);
tDataArray A(shape);
Now I would like to loop over all entries in A, e.g. to print them. If N was 2 for example I think I would write something like this
boost::array<tDataArray::index, 2> index;
for ( int i = 0; i < m; i++ )
{
for ( int j = 0; j < m; j++ )
{
index = {{ i, j }};
cout << A ( index ) << endl;
}
}
I've used an index object to access the elements as I think this is more flexible than the []-operator here.
But how could I write this without knowing the number of dimensions N. Is there any built-in way? The documentation of multi_array is not very clear on which types of iterators exist, etc.
Or would I have to resort to some custom method with custom pointers, computing indices from the pointers, etc.? If so - any suggestions how such an algorithm could look like?
Ok, based on the Google groups discussion already mentioned in one of the comments and on one of the examples from the library itself, here is a possible solution that lets you iterate over all values in the multi-array in a single loop and offers a way to retrieve the index for each of these elements (in case this is needed for some other stuff, as in my scenario).
#include <iostream>
#include <boost/multi_array.hpp>
#include <boost/array.hpp>
const unsigned short int DIM = 3;
typedef double tValue;
typedef boost::multi_array<tValue,DIM> tArray;
typedef tArray::index tIndex;
typedef boost::array<tIndex, DIM> tIndexArray;
tIndex getIndex(const tArray& m, const tValue* requestedElement, const unsigned short int direction)
{
int offset = requestedElement - m.origin();
return(offset / m.strides()[direction] % m.shape()[direction] + m.index_bases()[direction]);
}
tIndexArray getIndexArray( const tArray& m, const tValue* requestedElement )
{
tIndexArray _index;
for ( unsigned int dir = 0; dir < DIM; dir++ )
{
_index[dir] = getIndex( m, requestedElement, dir );
}
return _index;
}
int main()
{
double* exampleData = new double[24];
for ( int i = 0; i < 24; i++ ) { exampleData[i] = i; }
tArray A( boost::extents[2][3][4] );
A.assign(exampleData,exampleData+24);
tValue* p = A.data();
tIndexArray index;
for ( int i = 0; i < A.num_elements(); i++ )
{
index = getIndexArray( A, p );
std::cout << index[0] << " " << index[1] << " " << index[2] << " value = " << A(index) << " check = " << *p << std::endl;
++p;
}
return 0;
}
The output should be
0 0 0 value = 0 check = 0
0 0 1 value = 1 check = 1
0 0 2 value = 2 check = 2
0 0 3 value = 3 check = 3
0 1 0 value = 4 check = 4
0 1 1 value = 5 check = 5
0 1 2 value = 6 check = 6
0 1 3 value = 7 check = 7
0 2 0 value = 8 check = 8
0 2 1 value = 9 check = 9
0 2 2 value = 10 check = 10
0 2 3 value = 11 check = 11
1 0 0 value = 12 check = 12
1 0 1 value = 13 check = 13
1 0 2 value = 14 check = 14
1 0 3 value = 15 check = 15
1 1 0 value = 16 check = 16
1 1 1 value = 17 check = 17
1 1 2 value = 18 check = 18
1 1 3 value = 19 check = 19
1 2 0 value = 20 check = 20
1 2 1 value = 21 check = 21
1 2 2 value = 22 check = 22
1 2 3 value = 23 check = 23
so the memory layout goes from the outer to the inner indices. Note that the getIndex function relies on the default memory layout provided by boost::multi_array. In case the array base or the storage ordering are changed, this would have to be adjusted.
There is a lack of simple boost multi array examples. So here is a very simple example of how to fill a boost multi array using indexes and how to read all the entries using a single pointer.
typedef boost::multi_array<double, 2> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][2]);
// ------> x
// | 0 2 4
// | 1 3 5
// v
// y
double value = 0;
for(index x = 0; x < 3; ++x)
for(index y = 0; y < 2; ++y)
A[x][y] = value++;
double* it = A.origin();
double* end = A.origin() + A.num_elements();
for(; it != end; ++it){
std::cout << *it << " ";
}
// -> 0 1 2 3 4 5
If you don't need the index, you can simply do:
for (unsigned int i = 0; i < A.num_elements(); i++ )
{
tValue item = A.data()[i];
std::cout << item << std::endl;
}
Based on the answers before I produced this nice overloaded version of the insertion operator for boost::multi_arrays
using namespace std;
using namespace boost::detail::multi_array;
template <typename T , unsigned long K>
ostream &operator<<( ostream &os , const boost::multi_array<T , K> &A )
{
const T* p = A.data();
for( boost::multi_array_types::size_type i = A.num_elements() ; i-- ; ++p )
{
os << "[ ";
for( boost::multi_array_types::size_type k = 0 ; k < K ; ) {
os << ( p - A.origin() ) / A.strides()[ k ] % A.shape()[ k ]
+ A.index_bases()[ k ];
if( ++k < K )
os << ", ";
}
os << " ] = " << *p << endl;
}
return os;
}
It's just a streamlined version of answer 1, except it should work with any type T that has a working operator<<. I tested like
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
index x = 3;
index y = 2;
index z = 3;
array_type A( boost::extents[ x ][ y ][ z ] );
// Assign values to the elements
int values = 0;
for( index i = 0 ; i < x ; ++i )
for( index j = 0 ; j < y ; ++j )
for( index k = 0 ; k < z ; ++k )
A[ i ][ j ][ k ] = values++;
// print the results
cout << A << endl;
and it seems to work:
[ 0, 0, 0 ] = 0
[ 0, 0, 1 ] = 1
[ 0, 0, 2 ] = 2
[ 0, 1, 0 ] = 3
[ 0, 1, 1 ] = 4
[ 0, 1, 2 ] = 5
[ 1, 0, 0 ] = 6
[ 1, 0, 1 ] = 7
[ 1, 0, 2 ] = 8
[ 1, 1, 0 ] = 9
[ 1, 1, 1 ] = 10
[ 1, 1, 2 ] = 11
[ 2, 0, 0 ] = 12
[ 2, 0, 1 ] = 13
[ 2, 0, 2 ] = 14
[ 2, 1, 0 ] = 15
[ 2, 1, 1 ] = 16
[ 2, 1, 2 ] = 17
Hope this is useful to somebody, and thanks a lot for the original answers: it was very useful to me.

C++: compute a number's complement and its number of possible mismatches

I got a bit stuck with my algorithm and I need some help to solve my problem. I think an example would explain better my problem.
Assuming:
d = 4 (maximum number of allowed bits in a number, 2^4-1=15).
m_max = 1 (maximum number of allowed bits mismatches).
kappa = (maximum number of elements to find for a given d and m, where m in m_max)
The main idea is for a given number, x, to compute its complement number (in binary base) and all the possible combinations for up to m_max mismatches from x complement's number.
Now the program start to scan from i = 0 till 15.
for i = 0 and m = 0, kappa = \binom{d}{0} = 1 (this called a perfect match)
possible combinations in bits, is only 1111 (for 0: 0000).
for i = 0 and m = 1, kappa = \binom{d}{1} = 4 (one mismatch)
possible combinations in bits are: 1000, 0100, 0010 and 0001
My problem was to generalize it to general d and m. I wrote the following code:
#include <stdlib.h>
#include <iomanip>
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <stdint.h>
#include <vector>
namespace vec {
typedef std::vector<unsigned int> uint_1d_vec_t;
}
int main( int argc, char* argv[] ) {
int counter, d, m;
unsigned num_combination, bits_mask, bit_mask, max_num_mismatch;
uint_1d_vec_t kappa;
d = 4;
m = 2;
bits_mask = 2^num_bits - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
for ( unsigned m = 0 ; m < max_num_mismatch ; m++ ) {
// maximum number of allowed combinations
num_combination = boost::math::binomial_coefficient<double>( static_cast<unsigned>( d ), static_cast<unsigned>(m) );
kappa.push_back( num_combination );
for ( unsigned j = 0 ; j < kappa.at(m) ; j++ ) {
if ( m == 0 )
v[i][counter++] = i^bits_mask; // M_0
else {
bit_mask = 1 << ( num_bits - j );
v[i][counter++] = v[i][0] ^ bits_mask
}
}
}
}
return 0;
}
I got stuck in the line v[i][counter++] = v[i][0] ^ bits_mask since I was unable to generalize my algorithm to m_max>1, since I needed for m_max mismatches m_max loops and in my original problem, m is unknown until runtime.
i wrote a code that do what i want, but since i am newbie, it is a bit ugly.
i fixed m and d although this code would work fine for genral m and d.
the main idea is simple, assuming we would like to compute the complement of 0 up to two failure (d= 4,m=2), we will see that max number of possibilities is given by \sum_{i = 0)^2\binom{4}{i} = 11.
The complement to 0 (at 4 bits) is 15
With 1 bit possible mismatch (from 15): 7 11 13 14
with 2 bits possible mismatches (from 15): 3 5 6 9 10 12
i wanted that the output of this program will be a vector with the numbers 15 7 11 13 14 3 5 6 9 10 12 inside it.
i hope that this time i am more clear with presenting my question (although i also supplied the solution). I would appreachiate if someone could point out, in my code, ways to improve it and make it faster.
regards
#include <boost/math/special_functions/binomial.hpp>
#include <iostream>
#include <vector>
#define USE_VECTOR
namespace vec {
#if defined(USE_VECTOR) || !defined(USE_DEQUE)
typedef std::vector<unsigned int> uint_1d_vec_t;
typedef std::vector<uint_1d_vec_t> uint_2d_vec_t;
#else
typedef std::deque<unsigned int> uint_1d_vec_t;
typedef std::deque<uint_1d_vec_t> uint_2d_vec_t;
#endif
}
using namespace std;
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits );
double get_kappa( int m , int d );
int main( ) {
unsigned int num_elements , m , num_bits;
num_elements = 16;
num_bits = 4; // 2^4 = 16
m = 2;
double kappa = 0;
for ( unsigned int i = 0 ; i <= m ; i++ )
kappa += get_kappa( num_bits , i );
vec::uint_2d_vec_t Pointer( num_elements , vec::uint_1d_vec_t (kappa ,0 ) );
get_pointers_vec( Pointer , num_elements , m , num_bits );
for ( unsigned int i = 0 ; i < num_elements ; i++ ) {
std::cout << setw(2) << i << ":";
for ( unsigned int j = 0 ; j < kappa ; j++ )
std::cout << setw(3) << Pointer[i][j];
std::cout << std::endl;
}
return EXIT_SUCCESS;
}
double get_kappa( int n , int k ) {
double kappa = boost::math::binomial_coefficient<double>( static_cast<unsigned>( n ), static_cast<unsigned>(k) );
return kappa;
}
void get_pointers_vec( vec::uint_2d_vec_t &v , unsigned num_elemets , unsigned max_num_unmatch , unsigned num_bits ) {
int counter;
unsigned num_combination, ref_index, bits_mask, bit_mask;
vec::uint_1d_vec_t kappa;
bits_mask = pow( 2 , num_bits ) - 1;
for ( unsigned i = 0 ; i < num_elemets ; i++ ) {
counter = 0;
kappa.clear();
ref_index = 0;
for ( unsigned m = 0 ; m <= max_num_unmatch ; m++ ) {
num_combination = get_kappa( num_bits , m ); // maximum number of allowed combinations
kappa.push_back( num_combination );
if ( m == 0 ) {
v[i][counter++] = i^bits_mask; // M_0
}
else if ( num_bits == kappa.at(m) ) {
for ( unsigned k = m ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
}
else {
// Find first element's index
ref_index += kappa.at( m - 2 );
for( unsigned j = 0 ; j < ( kappa.at(m - 1) - 1 ) ; j++ ) {
for ( unsigned k = m + j ; k <= num_bits ; k++ ) {
bit_mask = 1 << ( num_bits - k );
v[i][counter++] = v[i][ref_index] ^ bit_mask;
}
ref_index++;
}
}
}
}
}