I have a vector of complex numbers and I need to sort them by their argument. Sadly, the numbers have type complex<int>, so function arg(c) returns an integer in range [-3,3] instead of a float and the numbers can't be sorted properly.
I've tried also
typedef complex<int> ci;
typedef complex<double> cd;
vector<ci> a;
sort(a.begin(), a.end(), [](ci v, ci u) { return arg(cd(v)) < arg(cd(u)); });
but it does not work either (compilation error: no matching function for call to ‘std::complex<double>::complex(ci&)).
Can I sort these numbers without changing their type?
You get the error because there is no converting constructor from std::complex<int> to std::complex<double> you have to construct the std::complex<double> by passing real and imaginary parts to the constructor:
#include <vector>
#include <complex>
#include <algorithm>
int main() {
std::vector<std::complex<int>> a;
std::sort(a.begin(), a.end(), [](const auto& v,const auto& u) {
return std::arg(std::complex<double>(v.real(),v.imag())) < std::arg(std::complex<double>(u.real(),u.imag()));
});
}
Note that you can also use atan2 directly without constructing the std::complex<double> as mentioned by user17732522.
Last but not least, reconsider if you really need int with std::complex. From cppreference:
T - the type of the real and imaginary components. The behavior is unspecified (and may fail to compile) if T is not float, double, or long double and undefined if T is not NumericType.
Basically this means that you need to check the implementation you are using whether it supports std::complex<int> at all.
Related
I want to multiply and divide all the elements of std::vector by constant in the same way as it is performed in C++ for ordinary types: at least the result should be integer when input vector has integer type and floating-point type otherwise.
I have found the code for multiplication based on std::multiplies and modified it with the replacement std::divides. As the result, the code works but not in the order I want it:
#include <iostream>
#include <vector>
#include <algorithm>
// std::vector multiplication by constant
// http://codereview.stackexchange.com/questions/77546
template <class T, class Q>
std::vector <T> operator*(const Q c, const std::vector<T> &A) {
std::vector <T> R(A.size());
std::transform(A.begin(), A.end(), R.begin(),
std::bind1st(std::multiplies<T>(),c));
return R;
}
// My modification for division. There should be integer division
template <class T, class Q>
std::vector <T> operator/(const std::vector<T> &A, const Q c) {
std::vector <T> R(A.size());
std::transform(A.begin(), A.end(), R.begin(),
std::bind1st(std::divides<T>(),c));
return R;
}
int main() {
std::vector<size_t> vec;
vec.push_back(100);
int d = 50;
std::vector<size_t> vec2 = d*vec;
std::vector<size_t> vec3 = vec/d;
std::cout<<vec[0]<<" "<<vec2[0]<<" "<<vec3[0]<<std::endl;
// The result is:
// 100 5000 0
size_t check = vec[0]/50;
std::cout<<check<<std::endl;
// Here the result is 2
// But
std::vector<double> vec_d;
vec_d.push_back(100.0);
vec_d = vec_d/50;
std::cout<<vec_d[0]<<std::endl;
// And here the result is 0.5
return 0;
}
How can I write my operator correctly ? I thought that std::bind1st would call division by c for each element, but it does the opposite somehow.
EDIT: I understand that I can write a loop, but I want to do a lot of divisions for big numbers, so I wanted it to be faster...
Using std::transform with C++11, I'd suggest making a lambda (see this tutorial) instead of using bind:
std::transform(A.begin(), A.end(), R.begin(), [c](T val) {
return val / c;
});
In my opinion, lambdas are almost always more readable than binding, especially when (like in your case) you're not binding all of the function's parameters.
Although if you're worried about performance, a raw for loop might be slightly faster, as there's no overhead of the function call and creating the lambda object.
According to Dietmar Kühl:
std::transform() may do a bit of "magic" and actually perform better than a loop. For example, the implementation may choose to vectorize the loop when it notices that it is used on a contiguous sequence of integers. It is, however, rather unlikely to be slower than the loop.
auto c_inverse= 1/c;
std::transform(A.begin(), A.end(), R.begin(), [c_inverse](T val) {
return val * c_inverse;
});
Similar to the other post, but it should be mentioned that rather than division, you will most likely see performance gains by multiplying by the inverse.
Why make it only for vectors? Here's a way to make more generic, to work with many types of containers:
template <class container, class Q>
container operator/(const container& A, const Q c) {
container R;
std::transform(std::cbegin(A), std::cend(A), std::back_inserter(R),
[c](const auto& val) {return val / c; });
return R;
}
Sure, it is expected to be a bit slower than with pre-allocation for a vector, since the back_inserter will allocate dynamically as it grows, but well, sometimes it might be appropriate to trade speed for genericity.
I have a vector of doubles, that I want to transform by multiplying by a double. I have it in mind to use std::transform, but I am having trouble working it out. How would I setup up a function to use my "factor" below to transform my init vector to my results vector?
Here is a representation of my code:
double a, b, factor;
std::vector<double> init;
std::vector<double> result;
// Code that initializes a, b, and
// fills in InitVec with timeseries (type double) data
factor = a/b;
result.resize(init.size())
std::transform(init.begin(), init.end(), result.begin(), /*function that multiplies init by factor*/)
is it as simple as:
std::transform(init.begin(), init.end(), result.begin(), *factor)
Thanks.
There are at least three different ways you can do this, including:
custom functor class
lamba instance
bound binary functor
See below for all three:
#include <iostream>
#include <algorithm>
#include <vector>
struct mult_by
{
double val;
mult_by(double v) : val(v) {}
double operator()(double arg) { return arg * val; };
};
int main()
{
using namespace std::placeholders;
double a = 1, b = 2, factor = a/b;
std::vector<double> init;
std::vector<double> result;
init.emplace_back(1.0);
init.emplace_back(2.0);
// using a functor
std::transform(init.begin(), init.end(), std::back_inserter(result), mult_by(factor));
// using a lambda
std::transform(init.begin(), init.end(), std::back_inserter(result),
[factor](double d){ return d * factor; });
// binding to a standard binary-op (std::multiplies)
std::transform(init.begin(), init.end(), std::back_inserter(result),
std::bind(std::multiplies<double>(), _1, factor));
// should report three pairs of 0.5 and 1
for (auto x : result)
std::cout << x << '\n';
}
Which you choose depends on preference or compiler limitations. Personally I would find the latter distasteful, but presented it as an option just because it is possible. I purposely left out std::for_each and outright hand-looped implementations, as those don't appear to be what you're looking for.
Best of luck.
You need a function which gets a double and returns a new double.
And you need to get factor in this function too.
Easy with a lambda expression:
std::transform(init.begin(), init.end(), result.begin(),
[factor](double val) -> double { return val*factor; }
);
To understand it better, it is a short version for the following code, except factor can be used in the function even if it is just a local variable where transform is called:
double modify(double val)
{
return val*factor;
}
...
std::transform(init.begin(), init.end(), result.begin(), modify);
Ie. a lambda expression is a unnamed function written inline as part of other stuff, and it can "capture" local variables from it´s caller context too.
I have a vector of pairs of int, and I want to add all the first elements of each pair. I have written following code
#include <iostream>
#include <numeric>
#include <vector>
#include <utility>
#define PII pair<int,int>
using namespace std;
int main() {
vector<pair<int,int>> v;
v.push_back(PII(1,2));
v.push_back(PII(3,4));
v.push_back(PII(5,6));
cout<<accumulate(v.begin(),v.end(),0,[](auto &a, auto &b){return a.first+b.first;});
return 0;
}
Here it is giving errors http://ideone.com/Kf2i7d.
The required answer is 1+3+5 = 9. I can't understand the errors it is giving.
In this call of the algorithm
cout<<accumulate(v.begin(),v.end(),0,[](auto &a, auto &b){return a.first+b.first;});
its third parameter is initialized by 0 and hence has deduced type int.
It corresponds to the accumulator of the algorithm that accumulates the values that are suplied by the second parameter of the lambda expression.
So you have to write
cout<<accumulate(v.begin(),v.end(),0,[](auto &a, auto &b){return a + b.first;});
As for me I would initialize it with integer literal of type long long int. For example
cout<<accumulate(v.begin(),v.end(),0ll,[](auto &a, auto &b){return a +b.first;});
std::accumulate iterates over each element and calls the supplied function with the current element and the current value of the accumulator.
The accumulator has type int, not pair<int, int> so you need to fix your lambda function to accept the right argument types.
I have a simple point structure
struct mypoint
{
int x;
int y;
};
and a vector of mypoints
vector<mypoint> myvector;
If I want to create a vector of int containing all the coordinates of my points (i.e. x1, y1, x2, y2, x3, y3, ...), I could easily do it in the following way
vector<mypoint>::iterator pt, ptend(myvector.end());
vector<int> newvector;
for(pt=myvector.begin(); pt!=ptend; ++pt)
{
newvector.push_back(pt->x);
newvector.push_back(pt->y);
}
Is there a way to obtain the same result in one (or two) line(s) of code using the C++11?
std::vector<int> extractIntsFromPoints(const std::vector<mypoint>& pointVector)
{
std::vector<int> retVector;
for (const auto& element : pointVector)
{
retVector.push_back(element.x);
retVector.push_back(element.y);
}
return retVector;
}
Call this function where you need the int vector.
I threw in the range-based for loop to make it extra C++11.
Since you're using C++11, you can use the new for syntax.
vector<int> newvector;
for( const auto &pt : myvector)
{
newvector.push_back(pt.x);
newvector.push_back(pt.y);
}
steal from the post: C++ std::transform vector of pairs->first to new vector
vector<int> items;
std::transform(pairs.begin(),
pairs.end(),
std::back_inserter(items),
[](const std::pair<int, int>& p) { return p.first; });
Here's about 4 lines, using a lambda:
vector<mypoint> points;
vector<int> iv;
points.push_back(mypoint(1,2));
points.push_back(mypoint(3,4));
points.push_back(mypoint(5,6));
for_each(points.cbegin(), points.cend(),
[&iv](const mypoint &pt) {
iv.push_back(pt.x);
iv.push_back(pt.y);
});
You could use a std::pair<> in which you push the coordinates using std::make_pair and then push the std::pair<> into the vector such as:
mypoint a_point;
std::pair<int, int> point = std::make_pair(a_point.x, a_point.y);
vector<std::pair<int, int>> vec.push_back(point).
Perhaps bulky but in two lines it works well and encapsulates a point rather than separating the magnitudes of each point axis and placing them inside a std::vector.
As reima already noted, if you only want to reference the existing sequence, it is sufficient to cast myvector.data() to int* (assuming sizeof(mypoint) == 2 * sizeof(int) holds).
However, if you explicitly want a copy of the flattened sequence, you are probably better off creating a small utility function like this:
template <typename T, typename U>
std::vector<T> flatten(std::vector<U> const& other) {
static_assert(std::is_trivially_copyable<U>::value,
"source type must be trivially copyable!");
static_assert(std::is_trivially_copy_constructible<T>::value,
"destination type must be trivially copy constructible!");
static_assert((sizeof(U) / sizeof(T)) * sizeof(T) == sizeof(U),
"sizeof(U) must be a multiple of sizeof(T)!");
return std::vector<T>(reinterpret_cast<T const*>(other.data()),
reinterpret_cast<T const*>(std::next(other.data(), other.size())));
}
template <typename U>
std::vector<typename U::value_type> flatten(std::vector<U> const& other) {
return flatten<typename U::value_type>(other);
}
reducing your code to
auto newvector = flatten<int>(myvector);
or - if you equip your mypoint struct with a (STL-conforming) value_type member type - even to
auto newvector = flatten(myvector);
Note, that this utility function is nothing more than a tweaked constructor using the inherently unsafe reinterpret_cast to convert mypoint pointers into int pointers.
To get rid of the safety caveats that go along with the use of reinterpret_cast, the flatten function uses some static_assert parachutes. So, it's better to hide all this in a seprate function.
Still, it uses a lot of C++11 features like auto, move construction, static_assert, type traits, std::next and vector::data() which pretty much strips down your call site code to a bare minimum.
Also, this is as efficient as it gets because the range constructor of vector will only perform the memory allocation and call uninitialized_copy, which will probably boil down to a call of memcpy for trivially copyable types.
Hi I want to (multiply,add,etc) vector by scalar value for example myv1 * 3 , I know I can do a function with a forloop , but is there a way of doing this using STL function? Something like the {Algorithm.h :: transform function }?
Yes, using std::transform:
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind(std::multiplies<T>(), std::placeholders::_1, 3));
Before C++17 you could use std::bind1st(), which was deprecated in C++11.
std::transform(myv1.begin(), myv1.end(), myv1.begin(),
std::bind1st(std::multiplies<T>(), 3));
For the placeholders;
#include <functional>
If you can use a valarray instead of a vector, it has builtin operators for doing a scalar multiplication.
v *= 3;
If you have to use a vector, you can indeed use transform to do the job:
transform(v.begin(), v.end(), v.begin(), _1 * 3);
(assuming you have something similar to Boost.Lambda that allows you to easily create anonymous function objects like _1 * 3 :-P)
Modern C++ solution for your question.
#include <algorithm>
#include <vector>
std::vector<double> myarray;
double myconstant{3.3};
std::transform(myarray.begin(), myarray.end(), myarray.begin(), [&myconstant](auto& c){return c*myconstant;});
I think for_each is very apt when you want to traverse a vector and manipulate each element according to some pattern, in this case a simple lambda would suffice:
std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; });
note that any variable you want to capture for the lambda function to use (say that you e.g. wanted to multiply with some predetermined scalar), goes into the bracket as a reference.
If you had to store the results in a new vector, then you could use the std::transform() from the <algorithm> header:
#include <algorithm>
#include <vector>
int main() {
const double scale = 2;
std::vector<double> vec_input{1, 2, 3};
std::vector<double> vec_output(3); // a vector of 3 elements, Initialized to zero
// ~~~
std::transform(vec_input.begin(), vec_input.end(), vec_output.begin(),
[&scale](double element) { return element *= scale; });
// ~~~
return 0;
}
So, what we are saying here is,
take the values (elements) of vec_input starting from the beginning (vec_input.begin()) to the end (vec_input.begin()),
essentially, with the first two arguments, you specify a range of elements ([beginning, end)) to transform,
range
pass each element to the last argument, lambda expression,
take the output of lambda expression and put it in the vec_output starting from the beginning (vec_output.begin()).
the third argument is to specify the beginning of the destination vector.
The lambda expression
captures the value of scale factor ([&scale]) from outside by reference,
takes as its input a vector element of type double (passed to it by std::transform())
in the body of the function, it returns the final result,
which, as I mentioned above, will be consequently stored in the vec_input.
Final note: Although unnecessary, you could pass lambda expression per below:
[&scale](double element) -> double { return element *= scale; }
It explicitly states that the output of the lambda expression is a double. However, we can omit that, because the compiler, in this case, can deduce the return type by itself.
I know this not STL as you want, but it is something you can adapt as different needs arise.
Below is a template you can use to calculate; 'func' would be the function you want to do: multiply, add, and so on; 'parm' is the second parameter to the 'func'. You can easily extend this to take different func's with more parms of varied types.
template<typename _ITStart, typename _ITEnd, typename _Func , typename _Value >
_ITStart xform(_ITStart its, _ITEnd ite, _Func func, _Value parm)
{
while (its != ite) { *its = func(*its, parm); its++; }
return its;
}
...
int mul(int a, int b) { return a*b; }
vector< int > v;
xform(v.begin(), v.end(), mul, 3); /* will multiply each element of v by 3 */
Also, this is not a 'safe' function, you must do type/value-checking etc. before you use it.