1

I would like to multiply a vector with a scalar. This vector was created using the accepted answer to this question of mine namely:

std::vector<int> n(N + 1);
  std::iota(begin(n), end(n), 0);

and I would like to multiply this vector, n, with a scalar (specifically of type double, if it is relevant here) called npi.

I have seen this answer to a previous question here, but it wasn't all that helpful. The way I attempted to implement it was by adding:

std::transform(n.begin(), n.end(), n.begin(),
           std::bind1st(std::multiplies<T>(),pin));

to my C++ program. This returned the compile error:

error: ‘T’ was not declared in this scope
                std::bind1st(std::multiplies<T>(),pin));

I would like to call the vector created by multiplying this vector with a scalar npi, so please do not give me code that will call this new vector n (i.e., overwriting my existing n vector).

EDIT:

If it will placate whomever voted to close this question, here is my full program:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <utility>
#include <unistd.h>
#include <algorithm>
#include <numeric>
/*#include <armadillo>*/

using namespace std;
/*using namespace arma;*/

double N  = 1000.0;
double x0 = 0;
double x1 = 100;
double pin = M_PI / double(N);

int main() {
  std::vector<int> n(N + 1);
  std::iota(begin(n), end(n), 0);
  std::transform(n.begin(), n.end(), n.begin(),
               std::bind1st(std::multiplies<T>(),pin));
  for(double i: n)
  {
    std::cout << i << '\n' << std::scientific;
  }
}
Community
  • 1
  • 1
Josh Pinto
  • 1,453
  • 4
  • 20
  • 37
  • Your vector is int. If you multiply it by a double scalar the values in the vector will still be int - the destination vector needs to be double so if you are going to modify in place change your vector to vector – Jerry Jeremiah Dec 08 '16 at 02:48
  • `double(N)` is a C-style cast. Casts are best avoided wherever possible (it's not needed here as N is already a double). If one is necessary, best to use C++-style `static_cast(N)` instead. – Jack Deeth Dec 08 '16 at 03:09
  • I *think* `begin(foo)` and `foo.begin()` are always equivalent (not certain though), in which case it's best to stick to one style throughout. This is a very minor and probably over-pedantic point, but consistency makes clearer code! – Jack Deeth Dec 08 '16 at 03:11
  • `N` is already a double, so the cast is not necessary. – Paul Rooney Dec 08 '16 at 03:13
  • Please clarify what `npi` should be -- `vector`, `vector`, or something else? Your existing code tries to modify `n` in-place (therefore giving `vector` output). – M.M Dec 08 '16 at 21:29

4 Answers4

3

For vector<int> output, one way is:

auto npi = n;

for( auto& i: npi )
    i *= pin;

If npi should be vector<double> (not clear from the question) then replace the first line with:

std::vector<double> npi( n.begin(), n.end() );
M.M
  • 138,810
  • 21
  • 208
  • 365
  • That would work if the OP wants to have a `vector` but OP wants a `vector` as the output. Otherwise, this is very pleasingly concise! – Jack Deeth Dec 08 '16 at 20:16
  • @JackDeeth OP didn't say that he wanted a `vector` output. And his original code attempts to do the transformation in-place, suggesting that he intended `vector` output; although he says in comments that he doesn't want to overwrite the original vector. – M.M Dec 08 '16 at 21:28
  • @MM It did not occur to me that `int a = int b * double c` could be a useful thing. Good call! – Jack Deeth Dec 08 '16 at 21:31
  • 1
    @JackDeeth you're probably right but I can imagine some applications for integer result (e.g. working on a lattice instead of continuous space) – M.M Dec 08 '16 at 21:33
2

You need to replace T by the type contained in the vector, in this case int. However you can probably simplify your code by using a lambda function here instead:

#include <algorithm> // for std::transform
#include <cmath>     // for M_PI
#include <iostream>  // for std::cout etc
#include <numeric>   // for std::iota
#include <vector>    // for awesome

int main() {
  std::vector<int> vec1(10);
  std::iota(vec1.begin(), vec1.end(), 0);

  int N = 42;

  std::vector<double> vec2(vec1.size()); // vec2 needs to be as big or bigger than vec1

  std::transform(vec1.begin(), vec1.end(), vec2.begin(),
                 [N](int i) { return i * M_PI / N; });

  for (auto a : vec1)
    std::cout << a << " ";
  std::cout << std::endl;

  for (auto a : vec2)
    std::cout << a << " ";
  std::cout << std::endl;
}

Here's an online example: http://melpon.org/wandbox/permlink/XrNxDND0steJmym8

Jack Deeth
  • 3,062
  • 3
  • 24
  • 39
  • Will this store the result as `n` (hence overwriting my `n` vector)? – Josh Pinto Dec 08 '16 at 02:48
  • Yes, this will. There's probably a way to write the output of `std::transform` to a new vector though... stand by... – Jack Deeth Dec 08 '16 at 02:50
  • Is it also worthwhile noting that `pin` isn't an integer? It's `pi/N` where N is an integer. Doesn't that mean the type `double` should be used? – Josh Pinto Dec 08 '16 at 02:54
  • No problem - I've expanded the example. You probably don't need to use `std::bind1st(std::multiplies` though. – Jack Deeth Dec 08 '16 at 03:06
1

If I have understood you correctly you need the following

std::vector<double> v;
v.reserve(n.size());

std::transform(n.begin(), n.end(), std::back_inserter( v ),
    std::bind1st(std::multiplies<double>(), pin));
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You can pass the scalar in the capture clause of the Lambda function and do the multiplication inside the lambda function itself

    #include <algorithm>
    #include <vector>
    
    std::vector<int> foo; 
    std::vector<int> bar;
    auto npi=4.0;
    std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), [&npi](auto& c){return c * npi;}
Spandyie
  • 914
  • 2
  • 11
  • 23