Related
I use Maxima CAS to create the list:
a:makelist(i,i,1,20);
result:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
I want to slim the list and leave only every third element. To find it I check index i of the list a :
mod(i,3)>0
to find elements.
My code :
l:length(a);
for i:1 thru l step 1 do if (mod(i,3)>0) then a:delete(a[i],a);
Of course it does not work because length of a is changing.
I can do it using second list:
b:[];
for i:1 thru l step 1 do if (mod(i,3)=0) then b:cons(a[i],b);
Is it the best method ?
There are different ways to solve this, as know already. My advice is to construct a list of the indices you want to keep, and then construct the list of elements from that. E.g.:
(%i1) a:makelist(i,i,1,20);
(%o1) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
(%i2) ii : sublist (a, lambda ([a1], mod(a1, 3) = 0));
(%o2) [3, 6, 9, 12, 15, 18]
(%i3) makelist (a[i], i, ii);
(%o3) [3, 6, 9, 12, 15, 18]
The key part is the last step, makelist(a[i], i, ii), where ii is the list of indices you want to select. ii might be constructed in various ways. Here is a different way to construct the list of indices:
(%i4) ii : makelist (3*i, i, 1, 6);
(%o4) [3, 6, 9, 12, 15, 18]
One simple way (I do not know which one is best or faster) with compact code: makelist(a[3*i],i,1,length(a)/3)
Test example:
l1:makelist(i,i,1,12)$
l2:makelist(i,i,1,14)$
l3:[2,3,5,7,11,13,17,19,23,29]$
for a in [l1,l2,l3] do (
b:makelist(a[3*i],i,1,length(a)/3),
print(a,"=>",b)
)$
Result:
[1,2,3,4,5,6,7,8,9,10,11,12] => [3,6,9,12]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14] => [3,6,9,12]
[2,3,5,7,11,13,17,19,23,29] => [5,13,23]
Is there a (fast) way to perform bits reverse of 32bit int values within avx2 register?
E.g.
_mm256_set1_epi32(2732370386);
<do something here>
//binary: 10100010110111001010100111010010 => 1001011100101010011101101000101
//register contains 1268071237 which is decimal representation of 1001011100101010011101101000101
Since I can't find a suitable dupe, I'll just post it.
The main idea here is to make use of pshufb's dual use a parallel 16-entry table lookup to reverse the bits of each nibble. Reversing bytes is obvious. Reversing the order of the two nibble in every byte could be done by building it into the lookup tables (saves a shift) or by explicitly shifting the low part nibble up (saves a LUT).
Something like this in total, not tested:
__m256i rbit32(__m256i x) {
__m256i shufbytes = _mm256_setr_epi8(3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);
__m256i luthigh = _mm256_setr_epi8(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15);
__m256i lutlow = _mm256_slli_epi16(luthigh, 4);
__m256i lowmask = _mm256_set1_epi8(15);
__m256i rbytes = _mm256_shuffle_epi8(x, shufbytes);
__m256i high = _mm256_shuffle_epi8(lutlow, _mm256_and_si256(rbytes, lowmask));
__m256i low = _mm256_shuffle_epi8(luthigh, _mm256_and_si256(_mm256_srli_epi16(rbytes, 4), lowmask));
return _mm256_or_si256(low, high);
}
In a typical context in a loop, those loads should be lifted out.
Curiously Clang uses 4 shuffles, it's duplicating the first shuffle.
Since the question would be a bit long, ill add that here, I also want to add a row in a vector to the Finald vector.
MatrixXf ProdA(7, 7);;
VectorXf Intd(7);
VectorXf Finald(7);
ProdA <<
7, 5, 1, 9, 11, 2, 0,
5, 2, 8, 3, 11, 3, 3,
3, 9, 0, 1, 3, 1, 7,
6, 0, 1, 9, 11, 33, 3,
3, 5, 3, 3, 4, 3, 3,
3, 9, 1, 1, 0, 1, 15,
6, 2, 6, 2, 5, 12, 3,
Intd << 4, 5, 2, 12, 4, 1, 6;
Finald << 0, 0, 0, 0, 0, 0, 0;
for (int i = 0; i < 7; i++){
Finald.row(i) += ProdA.rowwise().sum();
Finald.row(i) += Intd.row(i);
}
So far this is what I have got. Obviously I get an error if I put i in rowwise. So as an example, I want to add the first row of ProdA , and the first number of Intd into the first space in the Finald vector, and then loop through every row of ProdA and Intd, and sum them all into Finald.
Thanks in advance!
I'm not 100% certain that I correctly understand your problem, but the way I understood it, this should work:
VectorXf ones(7);
ones << 1, 1, 1, 1, 1, 1, 1;
Finald = ProdA * ones + Intd;
I'm not sure if your matrix library (which seems to be Eigen) stores vectors as row or column vectors. So you might have to use ones.transpose() instead.
Is it possible to initialize a static eigen matrix4d in a header file? I want to use it as a global variable.
I'd like to do something along the lines of:
static Eigen::Matrix4d foo = Eigen::Matrix4d(1, 2 ... 16);
Or similar to vectors:
static Eigen::Matrix4d foo = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
Here is a link to the eigen matrix docs. I can't seem to find how to do this from there.
A more elegant solution might include the use of finished(). The function returns 'the built matrix once all its coefficients have been set.'
E.g:
static Eigen::Matrix4d foo = (Eigen::Matrix4d() << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).finished();
On the lines of Dawid's answer (which has a small issue, see the comments), you can do:
static Eigen::Matrix4d foo = [] {
Eigen::Matrix4d tmp;
tmp << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16;
return tmp;
}();
Return value optimization takes care of the temporary, so no worries about an extra copy.
You can use initialization lambda like this:
static Eigen::Matrix4d foo = [] {
Eigen::Matrix4d matrix;
matrix << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16;
return matrix;
}();
I need to port a snippet written in Python to C++
but that snippet is using combinations from itertools in python.
The line that I'm really interested to porting over to C++ is this one:
for k in combinations(range(n-i),2*i):
range(n-i) in Python will generate a list from 0 to (n-i) - 1
Let n = 16, i = 5
print range(n-i)
outputs:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and python combinations will generate all possible combinations in that list.
e.g.
print list(combinations(range(n-i),2*i))
outputs:
[(0, 1, 2, 3, 4, 5, 6, 7, 8, 9),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 10),
(0, 1, 2, 3, 4, 5, 6, 7, 9, 10),
(0, 1, 2, 3, 4, 5, 6, 8, 9, 10),
(0, 1, 2, 3, 4, 5, 7, 8, 9, 10),
(0, 1, 2, 3, 4, 6, 7, 8, 9, 10),
(0, 1, 2, 3, 5, 6, 7, 8, 9, 10),
(0, 1, 2, 4, 5, 6, 7, 8, 9, 10),
(0, 1, 3, 4, 5, 6, 7, 8, 9, 10),
(0, 2, 3, 4, 5, 6, 7, 8, 9, 10),
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)]
I want to generate similar output using std::vector and next_permutation from C++ but I'm still getting erroneous results. This is my current approach:
for(int j = 0; j < n-i; j++) {
temp_vector.push_back(j);
}
That snippet is equivalent to range(n-i) in Python.
But the following snippet:
do {
myvector.push_back(temp_vector);
} while(next_permutation(temp_vector.begin(),temp_vector.begin()+2*i));
cout<<myvector.size()<<endl;
Is not equivalent to combinations(range(n-i),2*i)) in Python, and I've tried many variations and still haven't been able to come up with the results I'm expecting.
For example:
Let n = 16
i = 5
Python
>>> print len(list(combinations(range(n-i),2*i)))
11
C++
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> temp_vector;
vector< vector<int> > myvector;
int n = 16, i = 5;
for(int j = 0; j < n - i; j++) {
temp_vector.push_back(j);
}
do {
myvector.push_back(temp_vector);
} while(next_permutation(temp_vector.begin(), temp_vector.begin()+2*i));
cout<<myvector.size()<<endl;
return 0;
}
g++ combinations.cpp
./a.out
3628800
Any guidance will be greatly appreciated! Thanks a lot!
combinations and permutations are not the same thing.
A combination is an unordered list of a subset of the items from another set. A permutation is a unique order of the items in the list.
You're generating all combinations of 10 things from a list of 11 things, so you'll get 11 results, each one missing a different one of the original 11 items.
Generating every permutation will generate every unique order of the original 11 items. Since the items in this case are all unique that means the result would be 11! lists where each contains all 11 items. You're only generating permutations from the first 10 items however, so you're getting 10! lists, none of which contain the 11th item.
You need to find an algorithm for generating combinations instead of permutations.
There's no built-in algorithm for combinations. std::next_permutation can be used as part of an algorithm to generate combinations: See Generating combinations in c++.
Here's an old draft proposal for algorithms for combinations, including code.