assign multiple values to boost::numeric::ublas::vector in c++ - c++

I want to know how I can assign multiple values to a vector at once:
#include <iostream>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace boost::numeric::ublas;
int main()
{
vector<double> v1(3);
v1(0)=0;
v1(1)=0.1;
v1(2)=0.05;
v1(3)=0.25;
return 0;
}
I want to assign all the values at once.
something like:
v1 << 0,0.1,0.05,0.25;
I tried operator += and there is an error, but I think operator += works for std::vector not boost::....vector

Take a look at documentation examples http://svn.boost.org/svn/boost/trunk/libs/numeric/ublas/doc/samples/assignment_examples.cpp
Basically, you need v1 <<= 0, 1, 2;, see more examples in the docs. Unfortunately this library doesn't support initializer_list's yet: http://boost.2283326.n4.nabble.com/Initializing-from-an-initializer-list-td4647029.html

Related

how to fill a set in C++ with input from user

how can we fill a set in C++ from user input in one liner
I know we can store input in a variable and then use
set.insert(some_variable)
but cant we take input from user directly?
like set.insert(cin>>set[i])?
I am just a beginner.
You can copy the values into a std::set with std::copy_n. (Please see here)
The source will be the std::istream_iterator (described here) and the destination will be the std::inserter wrapper (described here).
Please see:
#include <iostream>
#include <set>
#include <iterator>
#include <algorithm>
int main() {
// Our set
std::set<int> s{};
// How many values do we want to read
const size_t numberOfUserInputs{ 3 };
// Copy values from std::cin to set
std::copy_n(std::istream_iterator<int>(std::cin), numberOfUserInputs, std::inserter(s, s.begin()));
// Debug output
for (int i : s) std::cout << i << '\n';
return 0;
}
no, you can't do this.
things that go with vector like
std::vector<int> he;
auto endf = he.end();
*he.insert(endf, 1) = 5;
will not go with set. insert returns const_iterator.

Converting an Eigen::VectorXd to an std::vector<double>

As the title says, I am trying to convert an Eigen::VectorXd to an std::vector. The vector is obtained by diagonalizing a matrix and then taking the first eigenvector of the process.
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
using namespace std;
int main()
{
vector<double> vec;
MatrixXd ones = MatrixXd::Ones(3,3);
VectorXd firstEvector;
SelfAdjointEigenSolver<MatrixXd> es(ones);
firstEvector = es.eigenvectors().col(1);
cout << "The first eigenvector of the 3x3 matrix of ones is:" << endl << firstEvector << endl;
vec(&firstEvector[0], firstEvector.data() + firstEvector.cols()*firstEvector.rows());
return 0;
}
I thought this was the way to do it, however, it doesn't work. I get the following error.
C:\CBProjects\eigenVectors\main.cpp|20|error: no match for call to '(std::vector<double>) (Eigen::DenseCoeffsBase<Eigen::Matrix<double, -1, 1>, 1>::Scalar*, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1> >::Scalar*)'|
I can't see what I am doing wrong. Any help would be greatly appreciated.
You are using a constructor syntax for the std::vector vec although the vector was already declared. That doesn't work.
There are two efficient possibilities to copy the content of an Eigen::VectorXd into a std::vector<double>. You can either construct a new std::vector vec2, like this:
vector<double> vec2(firstEvector.data(), firstEvector.data() + firstEvector.size());
or use the previously declared vector vec and transfer the data from the Eigen::VectorXd by using Eigen::Map. But in that case the std::vector first needs to be resized:
vec.resize(firstEvector.size());
Map<VectorXd>(vec.data(), vec.size()) = firstEvector;

using std::accumulate when there is pointer

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

how to deal with map of map?

I'm trying to find a solution for this problem
http://codeforces.com/problemset/problem/159/A
To find the solution, I thought of presenting the input by making a map of map.
And for this input my map should appear like this:
m["vasya"]={{"petya",1}}
m["petya"]={{"vasya",2}}
m["anya"]={{"ivan",2}}
m["ivan"]={{"anya",4}}
Below is my code.
and my assignment code:
// m[s1]=(ii(s2,t));
is wrong
my question is how can i assign to the map of map?
#include<iostream>
#include <cstdio>
#include <map>
#include <set>
#include <string>
#include<vector>
using namespace std;
int main(){
typedef map<string, int> ii;
map<string, ii> m;
int n,d;
cin>>n>>d;
string s1,s2,t;
for(int i=0;i<n;i++)
{
cin>>s1>>s2>>t;
// m[s1]=(ii(s2,t));
}
return 0;
}
Could anyone help?
You can write it like this:
m[s1][s2] = t;
I'm assuming you meant int t; rather than string t; since the last type in your map is int.
You want to make a more descriptive typedef than ii, but specifically you just want to add a new key-value pair into the map:
m[s1].insert(std::make_pair(s2, t));
Or if you want to split it up for clarity:
ii& submap = m[s1];
submap[s2] = t;
Or, if C++11 is available to you, exactly what you expressed in your question:
m[s1] = {{s2, t}};

Sequential sequence containers OR How to pack vectors

Imagine I have two vectors:
std::vector<int> A,B;
//Push a bunch of data into A
//Push a bunch of data into B
For whatever reason, I want to create an interface to these vectors such as follows:
packed combined(A,B);
for(packed::iterator i=combined.begin();i!=combined.end();++i)
*i+=1;
This will have the same effect as:
for(std::vector::iterator i=A.begin();i!=A.end();++i)
*i+=1;
for(std::vector::iterator i=B.begin();i!=B.end();++i)
*i+=1;
I could code up a class to do this, but it seems like the code may already exist in a library somewhere. Does anyone know if this is the case?
Alternatively, can you think of a cunning way to do this?
boost::join:
#include <vector>
#include <boost/range/join.hpp>
int main()
{
std::vector<int> a = {1,2,3}, b = {4,5,6};
for(int& i : boost::join(a, b)) {
i += 1;
}
}