mwater07
mwater07

Reputation: 133

Vector arrays, calculation dot product

I am trying write C++ programs that compute the dot product of two given vectors. In vectors a and b only nonzero elements will be stored into array of structures. Each time I am getting irrelevant results. The corrrect result is 50. I think i am not able to read the vectors properly into array of structures. Please advice. Thank you in advance

#include <iostream>
#include <vector>
using namespace std;

const int n=10; /* vector size limit */
struct element {
int x; /* original index of non-zero array element */
int val ; /* integer non-zero value at index x */
};
element row[n];
element col[n];

int i;
vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};

void generate_row_and_col()
 {
    for (i=0; i<=n; i++)
    {
        if(a[i]=!0)
        {
            row[i].x=i;
            row[i].val=a[i];
        }
    }
    for (i=0; i<=n; i++)
    {
        if(b[i]!=0)
        {
           col[i].x=i;
           col[i].val=b[i];
        }
    }
}
int dotproduct()
{
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].x!=-1 && col[j].x!=-1)
{
    if(row[i].x == col[j].x)
    {
        product=product+row[i].val*col[j].val;
        i++;
        j++;
    }
    else if(row[i].x<col[j].x)
    {
        i++;
    }
    else
    {
        j++;
    }
}
return product;
}
int main()
{
generate_row_and_col() ;
int r;
r=dotproduct();
cout<<"result="<<r<<endl;
return 0;
}

Upvotes: 0

Views: 4216

Answers (4)

mwater07
mwater07

Reputation: 133

I have done some changes on the code, it works fine now. But, during initialization row and col arrays on generate_row_and_col function , I only initialize indexes with non zero elements, rest of them are not initialized. This is not causing any error in this program, but in terms of good programming practice,those indexes with 0 values are not initiated and the arrays will look like(garbage, garbage,7, garbage, 5, garbage, garbage....). Can we just limit the generate_row_and_col function, so We can only store non zero value indexes. Thank you

#include <iostream>
#include <vector>
using namespace std;

const int n=11; /* vector size */

struct element {
int index; /* original index of non-zero array element */
int value ; /* integer non-zero value at index x */
};
element row[n];
element col[n];

vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};

void generate_row_and_col()
{
    for (int i=0; i<n; i++)
    {
        if(a[i]!=0)
        {
            row[i].index=i;
            row[i].value=a[i];
        }
    }
    for (int j=0; j<n; j++)
    {
        if(b[j]!=0)
        {
           col[j].index=j;
           col[j].value=b[j];
        }
    }
}
int dotproduct()
{
/* calculate the dot product of row and col output the result*/
int i=0;
int j=0;
int product=0;
while(row[i].value!=-1 && col[j].value!=-1)
{
    if(row[i].index == col[j].index)
    {
        product=product+row[i].value*col[j].value;
        i++;
        j++;
    }
    else if(row[i].index<col[j].index)
    {
        i++;
    }
    else
    {
        j++;
    }
}
return product;
}

int main()
{
    generate_row_and_col() ;
    int r;
    r=dotproduct();
    cout<<"Dot Product = "<<r<<endl;
    return 0;
}

Upvotes: 0

Hariom Singh
Hariom Singh

Reputation: 3632

You can simplify your code

#include <iostream>
#include <vector>

using namespace std;

template<class InputIt1, class InputIt2, class T>
T dot_product(InputIt1 first1, InputIt1 last1,
                InputIt2 first2, T value)
{
    while ((first1 != last1)&&(*first1!=-1) && (*first2 !=-1)) {
         value = value + *first1 * *first2;
         ++first1;
         ++first2;
    }
    return value;
}

const int n=10; /* vector size limit */
struct element {
    int x; /* original index of non-zero array element */
    int val ; /* integer non-zero value at index x */
};
element row[n];
element col[n];

int i;
vector<int> a={0,0,7,0,5,0,0,8,0,4,-1};
vector<int> b={0,0,0,5,6,0,0,0,0,5,-1};

int main()
{
    int r;
    r=dot_product(a.begin(), a.end(), b.begin(), 0);
    cout<<"result="<<r<<endl;
    return 0;
}

Output

50

Demo

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490148

The standard library has std::inner_product for exactly this purpose. Using it reduces your code to something like this:

#include <numeric>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> a = { 0,0,7,0,5,0,0,8,0,4 };
    std::vector<int> b = { 0,0,0,5,6,0,0,0,0,5 };

    std::cout << std::inner_product(a.begin(), a.end(), b.begin(), 0);
}

Upvotes: 2

sehe
sehe

Reputation: 393084

Using = !0 is a bug. That was supposed to be != 0.

I'm still guessing at the goal, but perhaps another cleaned version helps:

Live On Coliru

#include <iostream>
#include <vector>
#include <map>
using namespace std;

using Ints = vector<int>;
using Vec = map<int, int>;
Vec row, col;

Vec to_sparse_vec(Ints const& a) {
    Vec v;
    for (size_t i = 0; i < a.size(); ++i) {
        if (a[i] != 0) v[i] = a[i];
    }
    return v;
}

int dotproduct(Vec row, Vec col) {
    size_t n = max(row.rbegin()->first, col.rbegin()->first);

    int product = 0;
    for (size_t i = 0; i <= n; ++i) {
        if (row[i] && col[i])
            product += row[i] * col[i];
    }
    return product;
}

int main() {
    auto row = to_sparse_vec({ 0, 0, 7, 0, 5, 0, 0, 8, 0, 4 });
    auto col = to_sparse_vec({ 0, 0, 0, 5, 6, 0, 0, 0, 0, 5 });
    cout << "result=" << dotproduct(row, col) << endl;
}

This assumes the Vec representation is intended as a "sparse vector".

Result is 50 (dropped the -1 elements)

Upvotes: 1

Related Questions