So I am a new to this. I am trying to write a program with a function
double_product(vector< double > a, vector< double > b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include<iostream>
#include<vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<bouble> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i=0; i <=a.size()-1; i++)
for (int i=0; i <=b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main()
{
cout << product << endl;
return 0;
}
You have a pretty correct idea, at the fundamental level. A couple of basic building blocks extra and you'll be well on your way. Your scalar_product function is close, but not quite. You've created two loop iterators with the same name iterating over the same values. It should be fine to simply say
if (a.size() != b.size()) {} // error
for (int i=0; i < a.size(); i++)
product = product + (a[i])*(b[i]);
Now all you have to do is get some data, call it, and then output the result.
int main() {
std::vector<double> a;
std::vector<double> b;
// fill with the values
std::cout << scalar_product(a, b) << endl;
}
The whole class thing is completely unnecessary here- the only classes you need come in the Standard lib.
since I cannot comment I am forced to reply.
apparently there is exactly the same question, word by word, here:
Computing the scalar product of two vectors in C++
Related
This question already has answers here:
Declare large array on Stack
(4 answers)
Closed 9 months ago.
I am programming for simple matrices multiplication. However, for large values of matrix size, I faced with matrix overflow error. Could someone help me with this.
here the code!
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int r,c;
cout<<"Rows: ";
cin>>r; // 5000
cout<<"Clumns: ";
cin>>c; // 5000
int m[r][c];
for (int i=0;i<r;i++)
{
for (int j=0;j<c;j++)
{
m[i][j]=i+j;
cout<<setw(4)<<m[i][j];
}
cout<<endl;
}
}
I ran your program with different sizes. And the problem is simply that the array is too big. It works with smaller array sizes, but you can only put so much onto the stack.
So I did this:
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix {
public:
Matrix(int r, int c)
: rows(r), cols(c)
{
m = new int *[rows];
for (int index = 0; index < rows; ++index) {
m[index] = new int[cols];
}
}
int & at(int r, int c) {
return m[r][c];
};
int rows = 0;
int cols = 0;
int ** m = nullptr;
};
int main(int argc, char **argv)
{
int r = atoi(argv[1]);
int c = atoi(argv[2]);
Matrix m(r, c);
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
m.at(i, j) = i+j;
cout << setw(4) << m.at(i, j);
}
cout<<endl;
}
}
And that appears to work. Now, there are some things in here that are bad. I didn't write a destructor, so there's a memory leak. And I didn't do any range checking in the at() method. I was only showing what you could do for very large arrays.
Now, I'm going to beg you... PLEASE put white space in your code. You're going to have no end of errors when you shove everything together the way you do. Notice my for-loops have a lot more space than you do. I didn't fix everywhere, but the coding policy where I work is to include white space for readability. Walls of numbers and operators can be very, very hard to read.
Also, name your variables something longer than a single character.
Both these changes will dramatically reduce future bugs.
//I have a for loop that should construct an array of a certain class "Line" from two arrays of floats
for (int i=0; i<length; i++) Linearray[i](a[i], b[i]);
//my constructor function for line is:
pine::pine(float a, float b) {
st = a;
e = b;
}
//the error I'm getting is that I have no call operator defined.
//It's a little complicated to explain, so say all I can use is this constructor to fill that array.
//also assume arrays a and b are full of floats.
This Linearray[i](a[i], b[i]); tries to call the call operator operator()() (see also What are C++ functors and their uses?) from the Line class (which you probably haven't defined, hence the error) at the ith element in that list. You'd need to assign a new instance to call a constructor there:
Linearray[i] = Line(a[i], b[i]);
Although your question is already answered by Timo. Here is another way to achieve same goal
#include <iostream>
using namespace std;
class Line{
private:
int start, end;
public:
Line(){}
Line(float a, float b) {
start = a;
end = b;
}
};
int main() {
std::cout << "Hello World!\n";
int N = 5;
Line * arr = (Line*)malloc(sizeof(Line) * N);
for(auto i=0; i<N; i++){
arr[i] = Line(5,6);
}
}
I'm a beginner at C++ and to be honest, I've got no idea how to solve one task.
I have to create a matrix using a two dimensional array. It's size should be dependent on user's input (it should be like...int matrix[m][n], where m and n are the numbers entered by user). Then I'm supposed to fill it with random numbers from 0 to 100 and print it. Well, I can manage it.
The problem starts when I have to create a function finding the highest number from this array's row. The only parameter of this function can be the number of row entered by user (eg. int function(int i)).
The question is-how can I use the same array in multiple functions? Is there any way to do this, considering the fact that I'm a newbie?
Or maybe the task is formed incorrectly?
Sorry for the long post and thanks in advance
PS Someone asked for code, so here it is:
#include <iostream>
#include <cstdlib>
using namespace std;
int function1(int i)
{
//this is one of the functions I'm supposed to create-I described it earlier
}
int main()
{
int m,n;
cout<<"Matrix's size will be m rows and n columns. Please write m and n"<<endl;
cin>>m>>n;
int A[m][n];
int a,b;
for (a=0;a<m;a++)
{
for (b=0;b<n;b++)
{
A[a][b]=rand()%(100+1);
cout<<A[a][b]<<" ";
}
cout<<"\n";
}
}
EDIT: I'd like to thank you all for help guys. I asked my teacher about that and he finally responded. If you're curious, he told us (I hadn't heard it) to define an array like int[100][100] or higher and not allow user to input any higher numbers ;) That's not an optimal solution but surely a practical one. Thank you again!
The correct way to do this in C++ is to use a std::vector or std::array.
If you cannot do this because of artificial requirements, then there is simply no way you can declare a 2D array in C++ based on user input.
cin >> m >> n;
...
int array [m][n]; // not possible
int** wannabe; // not an array
int array [m * n]; // not possible
What you can do is a "mangled" 2D array:
int* mangled = new int[m * n];
Example of use:
class int_matrix
{
private:
int* mangled;
size_t rows;
size_t cols;
public:
int_matrix(size_t row, size_t col)
:rows(row),
cols(col)
{
mangled = new int[row * col];
}
int highest_in_row (size_t row)
{
...
}
};
Please note that this code requires that you follow the rule of three.
In C you would just have elegantly solved this by writing int array[m][n], but you are using C++ so you can't do that.
You can wrap your function into a class. In that class, you can have your array as member variable.
class A {
int **matrix;
public:
A(int rows, int columns) {
matrix = new int*[rows];
for(int i = 0; i < rows; ++i)
matrix[i] = new int[columns];
}
int function(int i); //you can use your matrix in this function
}
If you can't use classes, you can use global variables.
In a file.cpp
int **matrix;
int function(int i) {
//Do Something
}
//With rows the number of rows and columns the number of columns
//You can take these as parameters
int main() {
matrix = new int*[rows];
for(int i = 0; i < rows; ++i)
matrix[i] = new int[columns];
function(42);
}
If you declare a matrix like int int A[m][n]; where m and n aren't const, you can't pass it to a function. There are two ways to fix it:
1) Declare matrix with const size like int A[10][10];. In this case function which finds max will look like this:
int max_in_row(int matr[10][10], int row) {
int max = 0;
for (int col = 0; col < 10; ++col)
if (matr[row][col] > max)
max = matr[row][col];
return max;
}
and you can find max simple as int max = max_in_row(A, <row you want>);
2) (If you don't know size) Declare matrix as array of arrays:
int **A = new int*[n];
for (int i = 0; i < n; ++i)
A[i] = new int[m];
// fill A like you did
Then the function will look like
int max_in_row(int **matr, int row, int m) {
int max = 0;
for (int col = 0; col < m; ++col)
if (matr[row][col] > max)
max = matr[row][col];
return max;
}
and you can find max by int max = max_in_row(A, <row you want>, m);
The following is not standard C++ because it will only work if the compiler supports Variable Length Arrays. VLA were introduced in C99 and made optional in C11 but were never introduced in C++ standard - but some compilers support it even in C++ mode.
The hack will be to store the matrix address as a global void * and cast it to the proper pointer to VLA inside the function. This hack is required because at the moment of the global declaration you cannot know the number of columns of the matrix.
#include <iostream>
#include <cstdlib>
void *Matrix;
int Columns;
using namespace std;
int function1(int i)
{
typedef int MAT[Columns]; // BEWARE!!! VLA is not standard C++
MAT *mat = static_cast<MAT *>(Matrix);
int mx = mat[i][0];
for(int j=0; j<Columns; j++) {
cout << " " << mat[i][j];
if (mat[i][j] > mx) mx = mat[i][j];
}
std::cout << endl;
return mx;
}
int main()
{
int m,n;
cout<<"Matrix's size will be m rows and n columns. Please write m and n"<<endl;
cin>>m>>n;
int A[m][n]; // BEWARE!!! VLA is not standard C++
int a,b;
for (a=0;a<m;a++)
{
for (b=0;b<n;b++)
{
A[a][b]=rand()%(100+1); // Note that I now use a and b here !
cout<<A[a][b]<<" ";
}
cout<<"\n";
}
Matrix = static_cast<void *>(A);
Columns = n;
cout << "Enter row number to process: ";
cin >> a;
b = function1(a);
cout << "Max of row " << a << " is " << b << endl;
return 0;
}
Not really C++-ish, but at least it compiles and give expected results with clang version 3.4.1
I started writing in C++ a few months ago and am having some trouble using pointers. In the code that I've been writing for work, I've defined several matrices using the matrix_t class that I wrote. I created a vector that contains pointers to these matrices. I pass the vector to a function which accesses the matrices. Here's a simple example of what I'm trying to do:
#include <iostream>
#include "matrix_t.h"
using namespace std;
int mat_access (vector <matrix_t<int>*> &pmatrices)
{
matrix_t<int> mat = *pmatrices[0];
return mat.get_cell(0, 0);
/*get_cell(r, c) returns the value at row r, column c*/
}
int main()
{
vector <matrix_t<int>*> pmatrices(1);
matrix_t <int> mat (1, 1, 1);
/*mat_1(v, r, c) has r rows, c columns, and is filled with the value v*/
pmatrices[0] = &mat;
for (size_t i = 0; i < 5; i ++)
{
int k = mat_access(pmatrices);
cout << k;
}
}
If I step through the function while debugging, it works the first time the function mat_access is called. However, the second time that get_cell is called (even though its for the same row and column of the same matrix) a breakpoint is triggered and I get an error message in the output that says an invalid address is being accessed. I'm using App Verifier and the call stack location it returns has no source code. If I don't pass the vector of pointers to a function, but instead just access it directly in the main method, it works fine. Also, If I run the same code using vectors instead of matrices, it works fine. I don't think it's a problem with get_cell because I've used it at several other places in my code and I'm sure the indexing is correct. Here's what it looks like within the matrix_t class:
T get_cell (size_t row, size_t col) const
{ try
{
if (row >= n_rows || col >= n_cols)
throw myerror("Index out of bounds");
}
catch (exception &e)
{
cout << "Exception: " << e.what() << '\n';
}
return t_array [col * n_rows + row];
}
t_array contains the matrix elements and n_rows is the number of rows of the matrix. If all else fails, I'll just combine my matrices into one matrix and pass that to the function, but I'd like to understand why this isn't working. Any input would be appreciated.
Syntactically, I don't see any issues with your code. Try running this snippet (equivalent to what you have above) and see if you encounter the same error. If not, most likely the issue is in your matrix code.
int foo(vector<int*> &v) {
int x = *v[0];
return x;
}
int main() {
vector<int*> v(1);
int x = 9;
v[0] = &x;
for(int i = 0; i < 5; ++i) {
int y = foo(v);
cout << y << endl;
}
return 0;
}
I am trying to write a program with a function double_product(vector<double> a, vector<double> b) that computes the scalar product of two vectors. The scalar product is
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a) and end(a) are new in C++11, std::inner_product has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin and end to work with arrays though:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin and end above will only work for arrays, where the begin and end in C++11 (and later) will also work for normal collection types that define a .begin() and .end() (though it's trivial to add overloads to handle those as well, of course):
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
You can delete the class you have defined. You don't need it.
In your scalar_product function:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to call this function, you need to create 2 vector objects in your main(), fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
class are only needed to pack data together
a function should check its preconditions as soon as possible, those should be documented
a function should have postconditions, those should be documented
code reuse is the cornerstone of maintenable programs
With that in mind:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product algorithm directly but let's face it:
it requires four arguments, not two
it does not check for its arguments being of the same size
so it's better to wrap it.
Note: I used const& to indicate to the compiler not to copy the vectors.
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
g++ Scalar.cpp -o scalar
To run it simply type
./scalar
You should get 1.99 as the output of the above program.