Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Crafting a custom call to inner_product (C++ STL)

Tags:

c++

stl

I'm having trouble getting my head around how to use inner_product to combine a std::vector<float> and a std::vector<std::vector<float>>. Given, e.g., <2,3> and <<4,5>,<6,7>>, I'd like inner_product to produce

2*<4,5> + 3*<6,7> = <8,10> + <18,21> = <26,31>.

Supposing

vector<float> foo;

and

vector<vector<float>> bar;

are initialized and are of equal size, I don't know what UK1, UK2, and UK3 in

vector<float> ip = 
              inner_product(foo.begin(), foo.end(), bar.begin(), UK1, UK2, UK3);

should be. I suspect UK1 should be a vector filled with 0.0fs, of the same size as the vectors in bar. UK3 should perhaps be something like

std::transform(UK4.begin(), UK4.end(), UK4.begin(),
                                   std::bind1st(std::multiplies<float>(), UK5));

And I guess UK2 should somehow represent component-wise vector<float> addition!

I don't even want to think about how much more complex this will become when the vectors in bar are replaced by objects of a class with float attributes...

like image 562
user1148739 Avatar asked Nov 28 '25 04:11

user1148739


2 Answers

Define the add and multiply functions like this:

static vector<float> add(const vector<float> &a,const vector<float> &b)
{
  assert(a.size()==b.size());
  size_t n = a.size();
  vector<float> result(n);
  for (size_t i=0; i!=n; ++i) {
    result[i] = a[i]+b[i];
  }
  return result;
}

static vector<float> mul(const float &a,const vector<float> &b)
{
  size_t n = b.size();
  vector<float> result = b;
  for (size_t i=0; i!=n; ++i) {
    result[i] *= a;
  }
  return result;
}

And use it like this:

vector<float> zero(2,0);
vector<float> result =
  inner_product(a.begin(),a.end(),b.begin(),zero,add,mul);
like image 136
Vaughn Cato Avatar answered Nov 30 '25 18:11

Vaughn Cato


std::inner_product accumulates a sum. UK2 is the sum operation. UK1 is normally the neutral element of UK2. UK3 is the multiplication operation that multiplies corresponding elements of the two sequences and returns a summand for UK2.

I guess std::valarray should provide a more suitable container for this operation.

// this is c++11
#include <vector>
#include <valarray>
#include <algorithm>
#include <iostream>

int main ()
{
    std::valarray <int> zero = { 0, 0 };
    std::vector <int> foo = { 1, 2, 3 };
    std::vector <std::valarray<int>> bar = { { 3, 4 }, { 5, 6 }, { 7, 8 } };
    std::valarray<int> result = std::inner_product (foo.begin(), foo.end(), 
                                     bar.begin(), zero);
    for(auto n : result) {
        std::cout << n << ' '; 
    }               
    std::cout << std::endl;
}
like image 23
n. 1.8e9-where's-my-share m. Avatar answered Nov 30 '25 16:11

n. 1.8e9-where's-my-share m.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!