How can I initialize a SparseVector in Eigen ? The following code:
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse>
using namespace Eigen;
SparseVector<float> vec(3);
main()
{
vec(0)=1.0;
}
gives me the following error
error: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type
vec(0)=1.0;
by the way, vec[0]=1.0 doesn't work either.
Looking at the documentation I noticed Scalar& coeffRef(Index i), and it says:
Returns a reference to the coefficient value at given index i. This operation involes a log(rho*size) binary search. If the coefficient does not exist yet, then a sorted insertion into a sequential buffer is performed. (This insertion might be very costly if the number of nonzeros above i is large.)
So the following should work:
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse>
using namespace Eigen;
SparseVector<float> vec(3);
main()
{
vec.coeffRef(0)=1.0;
}
Not sure why they did it that way instead of using array overloading. Perhaps when it becomes IS_STABLE then they'll do it in a more typical C++ way?
Related
Is this the only solution when there is a pointer that points to a vector and we would like to use accumulate to sum up numbers?
Is there any simpler solution rather than writing a lambda function and using a four argument type of accumulating?
Also, for using std::sort, will the situation be the same?
Here is the code:
#include <random>
#include <vector>
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main() {
const int N=3;
auto p=make_unique<array<int,N>> ();
(*p)[0]=3;
(*p)[1]=4;
(*p)[2]=5;
sum=accumulate(p,?,0);
return 0;
}
To answer your immediate question:
std::accumulate(p->begin(), p->end(), 0);
The same syntax will work for other STL algorithms as well.
Other improvements to your code snippet:
Avoid using #include<bits/stdc++.h>, see this post. Similarly for using namespace std, it's considered bad practise.
const N=3 -> const auto N=3
std::array is not a vector and you can initialise it directly using initializer-list syntax:
const auto* obj = new std::array<int,3>{3,4,5};
Recently, I am trying to work on the Rcpp package to improve efficiency of computation in my work. However,I am not deep knowledged about C++, there are some strange behavoirs I can not understand. The below example show a simple tasks about derving weight of NumericVector, there are several questions:
When I use WAP=rev(WAP), it results in an incorrect output, I have to introduce a new variable to store the result so that I get the right output. I do not know why, should it NEVER use a 'x=f(x)' operation in C++ and Rcpp (must copy by clone instead) ?
About the CharacterVector method="eq", exactly I want to use a char or string type, however, it does not work with strncmp function (now I have to use method[0]), but I do not know how to look up the API of Rcpp functions in Rstudio?
I wonder whether there is a R-style grep, tolower function for conditions in Rcpp, I do not know which document I should refer to except for Rcpp suger, so that I can find the availiable base functions. Otherwise, I am thinking about calling R functions with Rcpp::function R_grep("grep"), but I do know whether this is the best way and recommended.
Any suggestions would be greatly appreciated.
#include <Rcpp.h>
#include <string>
#include <math.h>
#include <algorithm>
using namespace std;
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector cppweight(int N, CharacterVector method="eq", const bool reverse=false, const bool test=false){
NumericVector W(N);
NumericVector WAP(N);
NumericVector revWAP(N);
//method=tolower(method); //function not exists
if(strncmp(method[0],"eq",2)==0){
W=rep(1,N)/1.0*N;//convert int to float by multiplying 1.0
WAP=W/sum(W);
Rcout<< sum(W) << "\n";
} else if(strncmp(method[0],"ln",2)==0){
W=rev(seq(1,N))/1.0*N;
WAP=W/sum(W);
}
if(reverse){
if(test){
WAP=rev(WAP);//Why this result in incorrect result
revWAP=WAP;
}else{
revWAP=rev(WAP);
}
}else{
revWAP=WAP;
}
return(round(revWAP,3));
}
/*** R
cppweight(6,"ln",reverse=F,test=F)
cppweight(6,"ln",reverse=T,test=F)
cppweight(6,"ln",reverse=T,test=T)
*/
I'm trying to implement unordered_map> with using unordered_map::emplace
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
int main ()
{
unordered_map<char,vector<int>> amap;
amap.emplace('k',(2,9));
for(auto i : amap['k']){
cout << i;
}
}
I expected output as "99" because I constructed the vector with (2,9).
but actual outcome was "000000000" which the emplace constructed vector as (9), 0 being default and 9 as number of ints. I played around little more with other parameter values and realized the emplace only took last value in vector parameter. Why is it?
I can still accomplish the goal by doing
vector<int> v(2,9);
amap.emplace('k',v);
but just wondering why, and save one line of code.
amap.emplace('k',(2,9));
Here (2,9) is just comma separated values. Where everything before , is ignored.
So it is like
amap.emplace('k', (9));
gcc even throws a warning
warning: expression result unused [-Wunused-value]
You can use the below
amap.emplace('k', vector<int>(2,9));
The expression (2,9) is using the built-in comma operator, and the result of that is 9.
You need to provide a proper std::vector object, as in std::vector<int>(2, 9) instead.
I have a c array which contains valarrays as shown in the following code snipper,
#include <iostream>
#include <valarray>
#include <math.h>
using namespace std;
typedef uint uint32_t;
typedef std::valarray<uint32_t> uivector;
int main()
{
uivector a[] = { uivector(uint32_t(1),8), uivector(uint32_t(2),4), uivector(uint32_t(3),5) };
}
Now how do I access, say, the third element of the second valarray (the value there is 2), without making any copies and in a single line statement? Is it possible to overload the [] operator to achieve the same? something like a[1][2]?
The the third element of the second valarray is indeed a[1][2]. The subscripting operator is already overloaded by std::valarray. No copies are made, the value of the expression a[1][2] is the actual object contained in the valarray.
I am trying to create a STL (or boost) unordered_map with boost::mulprecision types e.g. cpp_int but gcc throws errors after trying to insert elements to this container.
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/unordered_map.hpp>
using namespace boost::multiprecision;
int main()
{
cpp_int z(123123123);
cpp_int x(123123123);
boost::unordered_map<cpp_int, cpp_int> data;
// line below will throw compilation errors
//data.insert(std::make_pair(z,x));
return 0;
}
Full error log is here
First of the errors:
In file included from /usr/include/boost/functional/hash/hash.hpp:529:0,
from /usr/include/boost/functional/hash.hpp:6,
from /usr/include/boost/unordered/unordered_map.hpp:20,
from /usr/include/boost/unordered_map.hpp:16,
from main.cpp:2:
/usr/include/boost/functional/hash/extensions.hpp: In instantiation of
........
main.cpp:13:34: required from here
/usr/include/boost/functional/hash/extensions.hpp:269:34: error: no matching function for call to ‘hash_value(const boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<> >&)’
return hash_value(val);
^
Is there a limitation to STL/boost container usage regarding boost's multiprecision types?
I am using boost 1.54.
EDIT:
The question of which this might be a duplicate uses boost::multiprecision's serialization support which has been added in boost 1.56 (at least according to differences in docs #1.55 and #1.56.
Also, in that question there has been no other approaches mentioned to solve this issue without serialization support in boost::multiprecision.
Your "question of which this might be a duplicate" documents a working technique in the question itself - hashing the string representation:
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/unordered_map.hpp>
using namespace boost::multiprecision;
template <typename T>
struct hash_str
{
size_t operator()(const T& t) const { return std::hash<std::string>()(t.str()); }
};
int main()
{
cpp_int z(123123123);
cpp_int x(123123123);
boost::unordered_map<cpp_int, cpp_int, hash_str<cpp_int>> data;
data.insert(std::make_pair(z,x));
}
Notes:
I don't know if cpp_int::str() outputs the full precision the type stores, but if it doesn't then distinct values yielding the same str() and hence hash will collide in the same bucket in the hash table, which won't break the functionality but moves away from O(1) towards O(N) performance. So, if by default str() doesn't display full precision but there's a way to force it, that would be a good idea if you deal in lots of values differing very slightly.
As with all uses of floating point types as keys, be careful as tiny rounding differences can lead to existing map entries not being found/matched, and hence unintended "duplicates" etc..
It your program is too slow and the profile proves the hashing is the cause, then worry about alternatives or upgrading boost....