Reputation: 133
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
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
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
Upvotes: 0
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
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:
#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