I have a 4000-by-4 matrix that needs to be initialized with different values.
I notice the following takes so much time in GCC that it virtually hangs up the compiler:
Eigen::Matrix<double,1000,500> mat;
mat.setZero();
mat << 1,2,3,4,
10,2,3,1,
(etc)
So, I thought I can also do this:
int i=0;
mat.row(i++) << 1,2,3,4;
mat.row(i++) << 10,2,3,1;
(etc)
Is there a more compiling-time and runtime-efficient way of doing this?
Just store the values in a POD-array (possibly aligned) and use an Eigen::Map on that:
EIGEN_ALIGN_TO_BOUNDARY(32) // align if you want to use SIMD
static const // leave the const, if you want to modify the data
double data[4*4] = { // 4000*4 in your case
0, 1, 2, 3,
4, 5, 6, 7,
8, 9,10,11,
12,13,14,15,
// ...
};
// again, leave the const, if you want to modify `mat`:
// RowMajor is easier to read when defining `data`
const static Eigen::Map<const Eigen::Matrix<double, 4, 4, Eigen::RowMajor>, Eigen::Aligned32> mat(data);
Related
How can I get the index an item in a std::array without running any loops?
#include <iostream>
#include <array>
std::array<int, 10> some_array = { 89, 56, 78, 96, 4, 34, 77, 2, 48, 3};
unsigned int GetIndexOfValue(unsigned int some_value) {
// How get the index of some_value here without running a loop?
}
int main() {
unsigned int some_value = 34;
std::cout << "The index of value passed is " << GetIndexOfValue(some_value) << std::endl;
}
Is it possible to do it using std::find?
You can use the functionality from the <algorithm> header, so you can avoid writing a raw loop, like this:
unsigned int GetIndexOfValue(unsigned int some_value) {
return std::distance(std::begin(some_array),
std::find(std::begin(some_array), std::end(some_array), some_value));
}
Here's a demo.
std::find(some_array.begin(), some_array.end(), some_value) - some_array.begin()
should do the trick (not tested).
Is it possible to do it using std::find?
Yes: with a std::array it's possible.
std::array<int, 10> some_array = { 89, 56, 78, 96, 4, 34, 77, 2, 48, 3};
auto idx = std::find(some_array.cbegin(), some_array.cend(), 34)
- some_array.cbegin();
std::cout << "The index of value passed is " << idx << std::endl;
With std::find() you get an iterator that, in the case of std::array (and std::vector) is a random access iterator and support the difference; so you can subtract the cbegin() iterator getting the index
But this doesn't mean that you can avoid a loop: the loop is inside std::find().
See also the answer from cigien that works also with containers not supporting random access iterators: you can use std::distance().
But, in case of a container supporting a non-random access iterator, I suppose that std::distance() can introduce a second loop. So, in this case, I suppose is better if you directly write a single loop.
I have an std::array and I have a variadic template function with the number of parameters that matches the size of the array. I need to assign the arguments to the elements of the array. In other words, in the code below I wish a to get values {1, 2, 3} and b to get values {1, 2, 3, 4, 5}
std::array<int, 3> a;
std::array<int, 5> b;
assign_values(a, 1, 2, 3);
assign_values(b, 1, 2, 3, 4, 5);
The question is how to implement the assign_values variadic template function.
I'm limited with the C++14 version.
Update:
The arguments can be of different types: assign_values(b, 1, 2u, 3., '4', 5l);
Sth like this:
template<class T, size_t N, class ... Values>
void assign_values(std::array<T,N>& arr, Values... vals) {
static_assert(N == sizeof...(vals));
int j = 0;
for (auto i : std::initializer_list< std::common_type_t<Values...> >{vals...})
arr[j++] = i;
}
Demo
I'm limited with the C++14 version
The good old trick of the unused array initialization (pre C++17 surrogate of template folding) should works (also C++11)
template <typename T, std::size_t N, typename ... Values>
void assign_values (std::array<T,N> & arr, Values... vals)
{
static_assert(N == sizeof...(vals));
using unused = int[];
int j = 0;
(void)unused { 0, (arr[j++] = vals, 0)... };
}
I have a question which way is the best to forward vector to bound function?
Below is code with two approaches. In production code vector will contain huge amount of data and I would like to avoid copying it as much as possible.
#include <iostream>
#include <vector>
#include <functional>
void foo(const std::vector<uint16_t>& v)
{
for(const auto& c : v)
{
std::cout << c;
}
std::cout << std::endl;
}
int main()
{
std::vector<uint16_t> vv{1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
auto f1 = std::bind(&foo, vv); // 1)
auto f2 = std::bind(&foo, std::move(vv)); // 2)
f1();
f2();
}
It really depends on what you want to do with the bound functions.
If they are going to be copied passed around (beyond the life of vv), this is correct (and is going to copy vv).
auto f1 = std::bind(&foo, vv); // 1)
This is also correct, (vv is not going to be copied initially at least.)
auto f2 = std::bind(&foo, std::move(vv)); // 2)
but you will not have access to vv after that point.
This is however the most likely scenario that I can deduce from your example:
if the bound function will be used locally while vv is still alive it is more likely from the example that want you want f3 to hold a "reference" to vv. This is done with the ref convention:
auto f3 = std::bind(&foo, std::ref(vv));
My question is more or less what's in the title; I'm wondering if there's a fast way to going through a sequence of bits and finding each bit that's set.
More detailed information:
I'm currently working on a data stucture that represents a set of objects. In order to support some operations I need, the structure must be able to perform very fast intersection of subsets internally. The solution I've come up with is to have each subset of the structure's superset represented by a "bit array", where each bit maps to an index in the array that holds the superset's data. Example: if bit #1 is set in a subset, then the element at index 1 in the superset's array is present in the subset.
Each subset consists of an array of ulong big enough that there's enough bits to represent the entire superset (if the superset contains 256 elements, the size of the array must be 256 / 64 = 4). To find the intersection of 2 subsets, S1 and S2, I can simply iterate through S1 and S2's array, and find the bitwise-and between the ulongs at each index.
Now back to what my question is really about:
In order to return the data of a subset, I have to iterate through all the bits in the subset's "bit array" and find the bits that are set. This is how I curently do it:
/// <summary>
/// Gets an enumerator that enables enumeration over the strings in the subset.
/// </summary>
/// <returns> An enumerator. </returns>
public IEnumerator<string> GetEnumerator()
{
int bitArrayChunkIndex = 0;
int bitArrayChunkOffset = 0;
int bitArrayChunkCount = this.bitArray.Length;
while(bitArrayChunkIndex < bitArrayChunkCount)
{
ulong bitChunk = bitArray[bitArrayChunkIndex];
// RELEVANT PART
if (bitChunk != 0)
{
int bit = 0;
while (bit < BIT_ARRAY_CHUNK_SIZE /* 64 */)
{
if(bitChunk.BitIsSet(bit))
yield return supersetData[bitArrayChunkOffset + bit];
bit++;
}
}
bitArrayChunkIndex++;
bitArrayChunkOffset += BIT_ARRAY_CHUNK_SIZE;
// END OF RELEVANT PART
}
}
Is there any obvious ways to optimize this? Any bit hacks to enable it to be done very fast? Thanks!
On INTEL 386+, you can use machine instruction BitSearchFirst.
Following - sample for gcc. This is little tricky for process 64-bit words,
but anyway works quick and efficient.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char **argv) {
uint64_t val;
sscanf(argv[1], "%llx", &val);
printf("val=0x%llx\n", val);
uint32_t result;
if((uint32_t)val) { // first bit is inside lowest 32
asm("bsfl %1,%0" : "=r"(result) : "r"(val));
} else { // first bit is outside lowest 32
asm("bsfl %1,%0" : "=r"(result) : "r"(val >> 32));
result += 32;
}
printf("val=%llu; result=%u\n", val, result);
return 0;
}
Also, in your use x64 architecture, you can try to use bsfq instruction, and remove "if/else"
Take an array of sixteen integers, initialized with the number of bits set for the integers from zero to fifteen (i.e. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4). Now take bitchunk % 16, and look up the result in the int array - that's the number of set bits in the first four bits of the chunk. Right shift four times, and repeat the entire operation fifteen more times.
You can do this with an array of 256 integers and 8 bit sub-chunks instead. I wouldn't recommend using an array of 4096 integers with 12 bit sub-chunks, that's getting a bit ridiculous.
int[] lookup = new int[16] {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
int bitCount = 0;
for(int i = 0; i < 16; i++) {
int firstFourBits = bitChunk % 16;
bitCount += lookup[firstFourBits];
bitChunk = butChunk >> 4;
}
I want to find the maximum values and indices by row of a matrix. I based this on an example on the eigen website (example 7).
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
MatrixXf::Index maxIndex;
VectorXf maxVal = mat.rowwise().maxCoeff(&maxIndex);
std::cout << "Maxima at positions " << endl;
std::cout << maxIndex << std::endl;
std::cout << "maxVal " << maxVal << endl;
}
Problem here is that my line
VectorXf maxVal = mat.rowwise().maxCoeff(&maxIndex);
is wrong. The original example has
float maxNorm = mat.rowwise().sum().maxCoeff(&maxIndex);
i.e. there is an additional reduction .sum() involved. any suggestions? I guess I just want the eigen equivalent to what in matlab I would write as
[maxval maxind] = max(mymatrix,[],2)
i.e. find maximum value and it's index over the second dimension of mymatrix and return in a (nrow(mymatrix),2) matrix.
thanks!
(sent to the eigen list as well, sorry for cross-posting.)
My guess is that this is not possible without using a for loop using the current api. As you said yourself, you can get the vector of maximum row values using
VectorXf maxVal = mat.rowwise().maxCoeff();
As far as I can tell from the API Documentation for maxCoeff() it will only write back a single index value. Following code (untested) should give you what you want:
MatrixXf::Index maxIndex[2];
VectorXf maxVal(2);
for(int i=0;i<2;++i)
maxVal(i) = mat.row(i).maxCoeff( &maxIndex[i] );
Besides the "for loop" solution by Jakob, you could also use libigl's igl::mat_max which functions like MATLAB's row-/column-wise max
Eigen::MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
Eigen::VectorXi maxIndices;
Eigen::VectorXf maxVals;
igl::mat_max(mat,2,maxVals,maxIndices);
Then maxVals would contain [9;7] and maxIndices would contain [3;2].