nomalization of complex number in c++ - c++

I am trying to convert a small code of Matlab in c++.
In matlab normalization of random number can be done easily as below:
val = x / norm(x)
where x contains random generated real and img part between 0 and 255 as below:
70.0000000000000 + 112.000000000000i
11.0000000000000 + 97.0000000000000i
24.0000000000000 + 195.000000000000i
210.000000000000 + 203.000000000000i
177.000000000000 + 47.0000000000000i
81.0000000000000 + 125.000000000000i
243.000000000000 + 114.000000000000i
8.00000000000000 + 165.000000000000i
After the normalization, the values in val are as below:
0.126554761381164 + 0.202487618209862i
0.0198871767884686 + 0.175368740771041i
0.0433902039021132 + 0.352545406704670i
0.379664284143491 + 0.367008808005375i
0.320002753778085 + 0.0849724826416384i
0.146441938169632 + 0.225990645323507i
0.439325814508897 + 0.206103468535038i
0.0144634013007044 + 0.298307651827029i
I really donot know how to do the similar work in c++.
I thought of doing something like below but soon got stuck.
int random_real_number;
int random_img_number;
vector<int > real_number;
vector<int> img_number;
int data_size_val= 8;
srand (time(NULL)); // Initialize random seed
for(int i=0;i< data_size_val;i++){
random_real_number = rand() % 255 + 0;
std::cout << random_real_number << std::endl;
random_img_number= rand() % 255 + 0;
std::cout << random_img_number << std::endl;
real_number.push_back(random_real_number);
img_number.push_back(random_img_number);
}
It would be great help if someone can help me in it.
Thanks in advance.

The function std::norm() computes something called the field norm, which is the sum of the squares of real and imag. You get the square root of that with std::abs(). So in the same vein as the example on the C++ website, you can do:
#include <vector>
#include <cassert>
#include <complex>
#include <iostream>
#include <iomanip>
int main() {
std::vector < std::complex < double > >
zarray { { 70, 112 }, { 11, 97 }, { 24, 195 }, { 210, 203 },
{ 177, 47 }, { 81, 125 }, { 243, 114 }, { 8, 165 } };
for ( auto z: zarray ) {
assert ( std::norm ( z ) == ( z.real() * z.real() + z.imag() * z.imag() ) );
assert ( std::norm ( z ) == ( z * std::conj ( z ) ) );
// assert ( std::norm ( z ) == ( std::abs ( z ) * std::abs ( z ) ) );
std::cout << "std::abs ( " << std::setw(9) << z << " ) = "
<< std::setw(7) << std::abs ( z )
<< ", z/abs = " << std::setw(19) << z / std::abs ( z ) << '\n';
}
}
which should return
std::abs ( (70,112) ) = 132.076, z/abs = (0.529999,0.847998)
std::abs ( (11,97) ) = 97.6217, z/abs = (0.11268,0.993631)
std::abs ( (24,195) ) = 196.471, z/abs = (0.122155,0.992511)
std::abs ( (210,203) ) = 292.077, z/abs = (0.718988,0.695022)
std::abs ( (177,47) ) = 183.134, z/abs = (0.966506,0.256643)
std::abs ( (81,125) ) = 148.95, z/abs = (0.543808,0.83921)
std::abs ( (243,114) ) = 268.412, z/abs = (0.905325,0.42472)
std::abs ( (8,165) ) = 165.194, z/abs = (0.048428,0.998827)
The first complex number in your example is divided by 553.12, but I don't really see how that would be the L2-norm of 70+112i.
For the C++ experts: compared to the example I had to comment out the last assert because it fails on some of the inputs, I'm not sure why that is.

Related

Finding sum of all binary expansions of numbers from 1 to n

Recently, I came across a question posted as a challenge at a competitive site. There it was asked to find the sum of all the decimal interpretation of binary representations of numbers from 1 to n. Suppose when n = 4, so, sum will be 1 + 10 + 11 + 100 = 122. Since this number could be very large so answer should be modulo 1000000007.
I came across the following solutions but was not able to optimize it.
#include<iostream>
#include<queue>
using namespace std;
int Mod(string s, int a)
{
int res = 0, i, l = s.size();
for( i = 0 ; i < l ; i++ )
{
res = ( res * 10 + s[i] - '0' ) % a;
}
return res;
}
int main()
{
int t;
cin >> t;
while(t--)
{
long long n;
cin >> n;
int Sum = 0, mod = 1000000007;
queue<string> q;
q.push("1");
while( n > 0 )
{
n--;
string s1 = q.front();
q.pop();
Sum = ( Sum + Mod(s1, mod) ) % mod;
string s2 = s1;
q.push(s1.append("0"));
q.push(s2.append("1"));
}
cout << Sum << endl;
}
return 0;
}
Constraints:
1 <= t <= 10^5, 1 <= n <= 10^18, Allowed Time = 1 sec. Any optimization help would be admirable. Thanks in advance.
After doing some calculative math finally I have come up with the solution. Thanks, to #largest_prime_is_463035818 for providing such hints. Here is my code:
#include<iostream>
#include<cmath>
#define mod 1000000007
using namespace std;
long long power(long long x, long long y)
{
long long res = 1LL;
while(y)
{
if( y & 1LL )
{
res = ( res * x ) % mod;
}
y >>= 1LL;
x = ( x * x ) % mod;
}
return res;
}
int main()
{
long long t;
cin >> t;
while(t--)
{
long long n, i, l, m, s = 0;
cin >> n;
if( n && (!( n & ( n - 1LL ) )) )
{
l = ceil(log2(n)) + 1LL;
}
else
{
l = ceil(log2(n));
}
for( i = 0LL ; i < l ; i++ )
{
if( n & ( 1LL << i ) )
{
m = ( ( ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) ) + 1LL ) + ( ( n % ( 1LL << ( i + 1LL ) ) ) % ( 1LL << i ) ) );
}
else
{
m = ( ( n / ( 1LL << ( i + 1LL ) ) ) * ( 1LL << i ) );
}
s = ( s + ( ( ( m % mod ) * power(10, i) ) % mod ) ) % mod;
}
cout << s << endl;
}
return 0;
}

Maximum product C++

I am given a few array of both negative and positive numbers.
I should Find the maximum product obtained from multiplying 2 adjacent numbers in the array.
This is the code I wrote :
#include <vector>
#include <iostream>
using namespace std;
int adjacentElementsProduct(vector<int> inputArray)
{
for(int i = 0; i < inputArray.size(); i++) {
if((inputArray[i] * inputArray[i+1])>(inputArray[i+1] * inputArray[i+2])) {
std::cout << inputArray[i] * inputArray[i+1] << "\n";
} else if((inputArray[i+1] * inputArray[i+2])>(inputArray[i+2] * inputArray[i+3])) {
std::cout << inputArray[i+1] * inputArray[i+2] << "\n";
} else if((inputArray[i+2] * inputArray[i+3])>(inputArray[i+3] * inputArray[i+4])) {
std::cout << inputArray[i+2] * inputArray[i+3] << "\n";
} else if((inputArray[i+3] * inputArray[i+4])>(inputArray[i+4] * inputArray[i+5])) {
std::cout << inputArray[i+3] * inputArray[i+4] << "\n";
} else {
std::cout << "Unknow" << "\n";
} return 1;
}
}
int main() {
adjacentElementsProduct({5, 8});
adjacentElementsProduct({1,2,3});
adjacentElementsProduct({1,5,10,9});
adjacentElementsProduct({5,1,2,3,1,4});
adjacentElementsProduct({4,12,3,1,5});
adjacentElementsProduct({3,6,-2,-5,7,3});
adjacentElementsProduct({9, 5, 10, 2, 24, -1, -48});
adjacentElementsProduct({5, 6, -4, 2, 3, 2, -23});
adjacentElementsProduct({-23, 4, -5, 99, -27, 329, -2, 7, -921});
adjacentElementsProduct({1,0,1,0,1000});
adjacentElementsProduct({1,2,3,0});
return 1 ;
}
Output:
40
6
90
5
48
18
50
30
-20
Unknow
6
The code only compares the product of inputArray[i] * inputArray[i+1] and inputArray[i+1] * inputArray[i+2] But I want to find the maximum product among all the numbers in array.
You want to loop over the input vector and compute the products of adjacent elements.
Then, you want to find the maximum of those products. You don't need all that hardcoded [i+1], [i+2], [i+3], ... shenanigans, you already have something that can get all those numbers for you -- a for loop.
int adjacentElementsProduct(vector<int> inputArray)
{
// Set initial max product to a very small number so that
// it is always replaced by our first product
int maxProduct = std::numeric_limits<int>::min();
for(int i = 0;
i < inputArray.size() - 1; /* because we will be doing i + 1 inside the loop */
i++) {
// Calculate product of this and next element
int product = inputArray[i] * inputArray[i + 1];
if (product > maxProduct)
maxProduct = product; // This product is the greatest so far,
// so keep it and get rid of the old max.
}
return maxProduct;
}
To explain how this works, let's look at the execution of the function for an example input. Let's say we do adjacentElementsProduct({5,1,2,3,1,4});
maxProduct is set to some very large negative number (let's say -99999999)
inputArray.size() is 6. inputArray.size() - 1 is 5.
i = 0. Is 0 < 5? Yes. Go inside loop
product = inputArray[0] * inputArray[1] = 5
is 5 > maxProduct (-99999999)? Yes. Set maxProduct = 5
Increment i to 1.
i = 1. Is 1 < 5? Yes. Go inside loop
product = inputArray[1] * inputArray[2] = 2
is 2 > maxProduct (5)? No.
Increment i to 2.
i = 2. Is 2 < 5? Yes. Go inside loop
product = inputArray[2] * inputArray[3] = 6
is 6 > maxProduct (5)? Yes. Set maxProduct = 6
Increment i to 3.
i = 3. Is 3 < 5? Yes. Go inside loop
product = inputArray[3] * inputArray[4] = 3
is 3 > maxProduct (6)? No.
Increment i to 4.
i = 4. Is 4 < 5? Yes. Go inside loop
product = inputArray[4] * inputArray[5] = 4
is 4 > maxProduct (6)? No.
Increment i to 5.
i = 5. Is 5 < 5? No.
Return maxProduct, which is 6.
I think your function is overkill. You can do this with a running maxima:
const unsigned int length = inputArray.length();
int maximum = inputArray[0] * inputArray[1];
for (unsigned int i = 1U; i < (length - 1U); ++i)
{
const int product = inputArray[i] * inputArray[i + 1];
if (product > maximum) maximum = product;
}
This can be further optimized but that is an exercise for the OP.
Edit 1: Via Pointers
This may be more optimal, but only assembly language will tell (or profiling):
const unsigned int length = inputArray.length();
int const * p_first = &inputArray[0];
int const * p_second = &inputArray[1];
int maximum = (*p_first++) * (*p_second++);
for (unsigned int i = 1u; i < (length - 1); ++i)
{
int product = (*p_first++) * (*p_second++);
if (product > maximum) maximum = product;
}
In the above code fragment, the two array locations are maintained in pointers. The pointers can be maintained in registers. No need to calculate the offset within the loop each time. Incrementing pointers is simple and quick operation. Some processors have instructions that can dereference a pointer and increment in a single instruction. Some compilers may perform this optimization depending on the optimization setting.
Edit 2: Tracking Previous Value
Another optimization is to reduce the memory accesses by about half, by remembering the previous value in the array:
const unsigned int length = inputArray.length();
int previous = inputArray[0];
int next = inputArray[1];
int maximum = previous * next;
previous = next;
for (unsigned int i = 1u; i < length; ++i)
{
next = inputArray[i];
const int product = previous * next;
if (product > maximum) maximum = product;
previous = next;
}
In the above code fragment, the previous array value is remembered in a variable. This eliminates the need to access the array for the previous value; only one array access is required.
The compiler may perform this optimization at higher optimization levels. The proof is to compare the assembly language of the variables fragments.
There's an algorithm in <numeric> that does this for you:
int adjacentElementsProduct(std::vector<int> const & inputArray)
{
// [[assert: inputArray.size > 1 ]]
return std::inner_product(inputArray.begin(), inputArray.end() - 1,
inputArray.begin() + 1,
0,
[](int i, int j) { return std::max(i, j); },
std::multiplies{});
}
which is about as efficient, and readable as it gets.
For starters the function should not output any message. It is the caller of the function will decide whether to output a message or not.
The function should return an iterator or a pair of iterators that point to the two adjacent elements with the maximum product.
As for your function implementation then it has undefined behavior because it can access non-existent elements of the vector.
I can suggest the following function definition as it is shown in the demonstrative program below.
#include <iostream>
#include <utility>
#include <vector>
#include <iterator>
std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator>
adjacentElementsProduct( const std::vector<int> &v )
{
std::pair<std::vector<int>::const_iterator, std::vector<int>::const_iterator>
p = { std::begin( v ), std::end( v ) };
if (not ( v.size() < 2 ))
{
p.second = std::next( std::begin( v ) );
long long int max_product = static_cast<long long int>( *p.first ) * *p.second;
for (auto prev = p.second, current = std::next( p.second );
current != std::end( v );
std::advance( prev, 1 ), std::advance( current, 1 ))
{
if (max_product < static_cast<long long int>( *prev ) * *current)
{
p = { prev, current };
}
}
}
return p;
}
int main()
{
std::vector<int> v = { 5, 8 };
auto p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,2,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,5,10,9 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 5,1,2,3,1,4 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 4,12,3,1,5 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 3,6,-2,-5,7,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 9, 5, 10, 2, 24, -1, -48 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 5, 6, -4, 2, 3, 2, -23 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { -23, 4, -5, 99, -27, 329, -2, 7, -921 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1, 0, 1, 0, 1000 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
v = { 1,2,3,0 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( *p.first ) * *p.second << '\n';
}
The program output is
40
6
90
6
48
21
48
30
-14
0
6
If you do not know yet iterators than the function can be defined the following way
#include <iostream>
#include <utility>
#include <vector>
std::pair<std::vector<int>::size_type, std::vector<int>::size_type>
adjacentElementsProduct( const std::vector<int> &v )
{
std::pair<std::vector<int>::size_type, std::vector<int>::size_type>
p = { 0, v.size() };
if (not ( v.size() < 2 ))
{
p.second = 1;
long long int max_product = static_cast<long long int>( p.first ) * p.second;
for (std::vector<int>::size_type i = 3; i < v.size(); i++ )
{
if (max_product < static_cast<long long int>( v[i - 1] ) * v[i] )
{
p = { i - 1, i };
}
}
}
return p;
}
int main()
{
std::vector<int> v = { 5, 8 };
auto p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,2,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,5,10,9 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 5,1,2,3,1,4 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 4,12,3,1,5 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 3,6,-2,-5,7,3 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 9, 5, 10, 2, 24, -1, -48 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 5, 6, -4, 2, 3, 2, -23 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { -23, 4, -5, 99, -27, 329, -2, 7, -921 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1, 0, 1, 0, 1000 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
v = { 1,2,3,0 };
p = adjacentElementsProduct( v );
std::cout << static_cast< long long int >( p.first ) * p.second << '\n';
}

Finding repetition of string pattern in a given string [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Could someone answer the below C++ interview question:
Given string: "song singing in hindi"
find repeated strings like as below :
single characters repetition:
Count of "s" = 2 Count of "o" = 0 Count of "n" = 5 Count of "g" = 3
..... etc
two character repetition
Count of "so" = 0 Count of "on" = 0 Count of "ng" = 3 Count of "in" = 4..... etc
Three character repetition
Count of "son" = 0 ....Count of "ing" = 1.... etc
Four character repetition
Count of "song" = 0 .....etc
Rs
Or even a recursive function would do. To remove the 'patterns' with a white space you can follow Vlad's approach with the string::find function.
#include <iostream>
#include <string>
#include <map>
class FRQ {
void Func(std::map<std::string, size_t> &frequencyTable, const std::string &m_str, const int stepping = 1) {
if (stepping == m_str.size()) {
frequencyTable[m_str]++;
return;
}
for (std::string::size_type i = 0, iMAX = m_str.size(); i < iMAX; ++i) {
frequencyTable[m_str.substr(i, stepping)]++;
}
Func(frequencyTable, m_str, stepping + 1);
}
public:
std::map<std::string, size_t> *operator()(const std::string &str) {
std::map<std::string, size_t> *fTable = new std::map<std::string, size_t>();
Func(*fTable, str);
return fTable;
}
};
int main(void) {
using namespace std;
string s = "HiYo HiYo";
FRQ frq;
map<string, size_t> *frequenceTable = frq(s);
cout << "Patterns: " << frequenceTable->size() << endl;
for (const auto& ptr : *frequenceTable)
cout << "[ '" << ptr.first << "'::" << ptr.second << " ]" << endl;
delete frequenceTable;
return 0;
}
Here is a straightforward approach
#include <iostream>
#include <string>
#include <map>
int main()
{
std::string s = "song singing in hindi";
for ( std::string::size_type i = 1; i <= s.size(); i++ )
{
std::map<std::string, size_t> m;
for ( std::string::size_type j = 0; j < s.size() - i + 1; j++ )
{
m[std::string( s, j, i )]++;
}
for ( const auto &p : m )
{
std::cout << "( \"" << p.first << "\", " << p.second << " ) ";
}
std::cout << std::endl;
}
return 0;
}
If you want to exclude patters with an embedded blank you can rewrite the program the following way
#include <iostream>
#include <string>
#include <map>
int main()
{
std::string s = "song singing in hindi";
for ( std::string::size_type i = 1; i <= s.size(); i++ )
{
std::map<std::string, size_t> m;
for ( std::string::size_type j = 0; j < s.size() - i + 1; j++ )
{
std::string t( s, j, i );
if ( t.find( ' ' ) == std::string::npos )
{
m[t]++;
}
}
if ( !m.empty() )
{
for ( const auto &p : m )
{
std::cout << "( \"" << p.first << "\", " << p.second << " ) ";
}
std::cout << std::endl;
}
}
return 0;
}
The output is
( "d", 1 ) ( "g", 3 ) ( "h", 1 ) ( "i", 5 ) ( "n", 5 ) ( "o", 1 ) ( "s", 2 )
( "di", 1 ) ( "gi", 1 ) ( "hi", 1 ) ( "in", 4 ) ( "nd", 1 ) ( "ng", 3 ) ( "on", 1 ) ( "si", 1 ) ( "so", 1 )
( "gin", 1 ) ( "hin", 1 ) ( "ind", 1 ) ( "ing", 2 ) ( "ndi", 1 ) ( "ngi", 1 ) ( "ong", 1 ) ( "sin", 1 ) ( "son", 1 )
( "ging", 1 ) ( "hind", 1 ) ( "indi", 1 ) ( "ingi", 1 ) ( "ngin", 1 ) ( "sing", 1 ) ( "song", 1 )
( "hindi", 1 ) ( "ingin", 1 ) ( "nging", 1 ) ( "singi", 1 )
( "inging", 1 ) ( "singin", 1 )
( "singing", 1 )

How to convert a number to 0.mynumber

How can i convert a number to 0. and the number?
so
int i = 50;
float a = 0.i //wrong code :D
or what?
how can i do it?
float a = i;
while( a >= 1.0f ) a /= 10.0f;
It's ugly, but I think this works:
int i = 50;
std::stringstream ss;
ss << "0." << i;
float a;
ss >> a;
What about:
#include <cmath>
#include <initializer_list>
#include <iostream>
float zero_dot( float m ) {
return m / pow( 10.0, floor( log( m ) / log( 10.0 ) ) + 1 );
}
int main() {
for( auto const & it: { 5.0, 50.0, 500.0, 5509.0, 1.0 } ) {
std::cout << it << ": " << zero_dot( it ) << std::endl;
}
return 0;
}
The output is:
5: 0.5
50: 0.5
500: 0.5
5509: 0.5509
1: 0.1
The computation does not use any loop.

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++;
}
}
}
}
}