Multiply vector elements by a scalar value using STL - c++

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.

Related

How to use divides and for_each?

I have:
vector<double> ved1 = { 1,2,3,4,5,6,7,8,9,10 };
vector<double> ved2 = { 11,12,13,14,15,16,17,18,19,20 };
vector<double> ved3(10);
and I want to have ved3=ved3/2 but I can't get it correctly, the result is 2/ved3;
How to use divides?
transform(ved1.begin(), ved1.end(), ved2.begin(), ved3.begin(), plus<double>());
transform(ved3.begin(), ved3.end(), ved3.begin(), bind1st(divides<double>(),2));`
I want cos(ved2), but I cannot get it. What's wrong with my code?
double cos_1(double x) { return cos(x); }
for_each(ved2.begin(), ved2.end(), cos_1);
bind1st will bind 2 to the 1st argument of divides, and then transform will supply each element of ved3 to divides as the second argument. So the result will be divides(2, ved3[0]), divides(2, ved3[1]) and so on.
If you want to calculate divides(ved3[...], 2) instead, use bind2nd(divides<double>(), 2). This way, 2 will be bound to the second argument, leaving the first one vacant for transform.
How to use std::for_each to apply a cosine elementwise
std::for_each does not fill some output; or necessarily change the input container/range. It just applies an invocable object to each element of a range. If the function has no "side effects" - than the for_each would be useless. Specifically, in your case - you're computing the cosine of each value, but not doing anything with it.
If you want to change the values in-place, you'll need to specifically do that:
void apply_cos(double& x) { x = std::cos(x); }
// ...
for_each(ved2.begin(), ved2.end(), apply_cos);
or using a lambda expression:
for_each(ved2.begin(), ved2.end(), [](double& x) { x = cos(x); });
Note the use of a reference input to the function rather than a value: double& x, not double x. That means that when you change x in apply_cos(), the value in the input range to std::for_each changes.

how to sum up a vector of vector int in C++ without loops

I try to implement that summing up all elements of a vector<vector<int>> in a non-loop ways.
I have checked some relevant questions before, How to sum up elements of a C++ vector?.
So I try to use std::accumulate to implement it but I find it is hard for me to overload a Binary Operator in std::accumulate and implement it.
So I am confused about how to implement it with std::accumulate or is there a better way?
If not mind could anyone help me?
Thanks in advance.
You need to use std::accumulate twice, once for the outer vector with a binary operator that knows how to sum the inner vector using an additional call to std::accumulate:
int sum = std::accumulate(
vec.begin(), vec.end(), // iterators for the outer vector
0, // initial value for summation - 0
[](int init, const std::vector<int>& intvec){ // binaryOp that sums a single vector<int>
return std::accumulate(
intvec.begin(), intvec.end(), // iterators for the inner vector
init); // current sum
// use the default binaryOp here
}
);
In this case, I do not suggest using std::accumulate as it would greatly impair readability. Moreover, this function use loops internally, so you would not save anything. Just compare the following loop-based solution with the other answers that use std::accumulate:
int result = 0 ;
for (auto const & subvector : your_vector)
for (int element : subvector)
result += element;
Does using a combination of iterators, STL functions, and lambda functions makes your code easier to understand and faster? For me, the answer is clear. Loops are not evil, especially for such simple application.
According to https://en.cppreference.com/w/cpp/algorithm/accumulate , looks like BinaryOp has the current sum on the left hand, and the next range element on the right. So you should run std::accumulate on the right hand side argument, and then just sum it with left hand side argument and return the result. If you use C++14 or later,
auto binary_op = [&](auto cur_sum, const auto& el){
auto rhs_sum = std::accumulate(el.begin(), el.end(), 0);
return cur_sum + rhs_sum;
};
I didn't try to compile the code though :). If i messed up the order of arguments, just replace them.
Edit: wrong terminology - you don't overload BinaryOp, you just pass it.
Signature of std::accumulate is:
T accumulate( InputIt first, InputIt last, T init,
BinaryOperation op );
Note that the return value is deduced from the init parameter (it is not necessarily the value_type of InputIt).
The binary operation is:
Ret binary_op(const Type1 &a, const Type2 &b);
where... (from cppreference)...
The type Type1 must be such that an object of type T can be implicitly converted to Type1. The type Type2 must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type2. The type Ret must be such that an object of type T can be assigned a value of type Ret.
However, when T is the value_type of InputIt, the above is simpler and you have:
using value_type = std::iterator_traits<InputIt>::value_type;
T binary_op(T,value_type&).
Your final result is supposed to be an int, hence T is int. You need two calls two std::accumulate, one for the outer vector (where value_type == std::vector<int>) and one for the inner vectors (where value_type == int):
#include <iostream>
#include <numeric>
#include <iterator>
#include <vector>
template <typename IT, typename T>
T accumulate2d(IT outer_begin, IT outer_end,const T& init){
using value_type = typename std::iterator_traits<IT>::value_type;
return std::accumulate( outer_begin,outer_end,init,
[](T accu,const value_type& inner){
return std::accumulate( inner.begin(),inner.end(),accu);
});
}
int main() {
std::vector<std::vector<int>> x{ {1,2} , {1,2,3} };
std::cout << accumulate2d(x.begin(),x.end(),0);
}
Solutions based on nesting std::accumulate may be difficult to understand.
By using a 1D array of intermediate sums, the solution can be more straightforward (but possibly less efficient).
int main()
{
// create a unary operator for 'std::transform'
auto accumulate = []( vector<int> const & v ) -> int
{
return std::accumulate(v.begin(),v.end(),int{});
};
vector<vector<int>> data = {{1,2,3},{4,5},{6,7,8,9}}; // 2D array
vector<int> temp; // 1D array of intermediate sums
transform( data.begin(), data.end(), back_inserter(temp), accumulate );
int result = accumulate(temp);
cerr<<"result="<<result<<"\n";
}
The call to transform accumulates each of the inner arrays to initialize the 1D temp array.
To avoid loops, you'll have to specifically add each element:
std::vector<int> database = {1, 2, 3, 4};
int sum = 0;
int index = 0;
// Start the accumulation
sum = database[index++];
sum = database[index++];
sum = database[index++];
sum = database[index++];
There is no guarantee that std::accumulate will be non-loop (no loops). If you need to avoid loops, then don't use it.
IMHO, there is nothing wrong with using loops: for, while or do-while. Processors that have specialized instructions for summing arrays use loops. Loops are a convenient method for conserving code space. However, there may be times when loops want to be unrolled (for performance reasons). You can have a loop with expanded or unrolled content in it.
With range-v3 (and soon with C++20), you might do
const std::vector<std::vector<int>> v{{1, 2}, {3, 4, 5, 6}};
auto flat = v | ranges::view::join;
std::cout << std::accumulate(begin(flat), end(flat), 0);
Demo

Trying to provide operator that divides integer-type std::vector by constant

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.

How do I pass an Eigen matrix row reference, to be treated as a vector?

I have a function that operates on a Vector reference, e.g.
void auto_bias(const Eigen::VectorXf& v, Eigen:Ref<Eigen::VectorXf>> out)
{
out = ...
}
and at some point I need to have this function operate on a Matrix row. Now, because the default memory layout is column-major, I can't just Map<> the data the row points to into a vector. So, how do I go about passing the row into the above function so that I can operate on it?
The not-so-pretty solution is to have a temp vector, e.g.
VectorXf tmpVec = matrix.row(5);
auto_bias(otherVector, tmpVec);
matrix.row(5) = tmpVec;
but is there a way of doing it directly?
You can modify your function to take a reference to the row type (which is a vector expression) instead of a vector. This is really only manageable with a template to infer that type for you:
#include <iostream>
#include <Eigen/Core>
template<typename V>
void set_row(V&& v) {
v = Eigen::Vector3f(4.0f, 5.0f, 6.0f);
}
int main() {
Eigen::Matrix3f m = Eigen::Matrix3f::Identity();
set_row(m.row(1));
std::cout << m;
return 0;
}
You can allow Ref<> to have a non default inner-stride (also called increment), as follows:
Ref<VectorXf, 0, InnerStride<>>
See the example function foo3 of the Ref's documentation.
The downside is a possible loss of performance even when you are passing a true VectorXf.

How to use a sequence of statements in Boost.Phoenix together with std::transform?

I'd like to use Boost.Phoenix to create a lambda function that consists of a few lines of code and then "returns" a value so I can use it together with std::transform.
Like this:
std::transform(a.begin(), a.end(), b.begin(),
(
//Do something complicated here with the elements of a:
statement1,
statement2,
statement3
//Is there a way to return a value here?
)
);
With std::for_each this would work perfectly, but with std::transform it does not compile because the comma operator returns void. How can I return a value from a lambda function like this?
Edit: I changed the code fragment because what I wrote in the first place led to misunderstandings about what I want to do.
No, this isn't possible. From the Boost.Phoenix v2 statement docs:
Unlike lazy functions and lazy operators, lazy statements always return void.
(Note that this same assertion is in the Boost.Phoenix v3 docs as well.)
In functional programming, it's not the intention to change state. However, instead of using for_each, you may use accumulate. Accumulating implies you have a 'starting value' (e.g. m=1,n=0), and a function that 'adds' a value to an output value:
#include <vector>
struct MN { int m, n;
MN(int m,int n):m(m),n(n){}
static MN accumulate( MN accumulator, int value ) {
return MN( accumulator.m + value, accumulator.n * value );
}
}; // your 'state'
int main(){
std::vector<int> v(10,10); // { 10, 10, ... }
MN result = std::accumulate( v.begin(), v.end(), MN(0,1), MN::accumulate );
printf("%d %d", result.m, result.n );
}
I'm unfamilar with Phoenix, but probably there is a way to define the MN::accumulate function in terms of it.