Task 4: Vector and matrix operations
Note: All occurrences of the word vector in this assignment without an explicit std::
prefix mean vector in the mathematical sense.
Task:
Write a program that implements the multiplication of integer vectors and matrices using std::vectors
. The program must support the following three possible operations:
- Dot product of two vectors (also called scalar product or inner product)
- Matrix-vector product (application of a matrix to a column vector)
- Matrix product
Implement the following program structure:
- Query for the two operands from the input: the left operand first, then the right operand.
- If none of the three operators described above can be applied, output error then end the program.
- If the two operands have mismatched sizes (e.g. the dot product of a 2D vector and a 3D vector), output error then end the program.
- Output the result of the operation then end the program.
Note: We already provide a partial implementation of this program in main.cpp
.
Recommendations:
- We provide functions to read and write matrices, vectors, and scalars in io.h. Use them!
- Use one dimensional
std::vectors
to represent vectors and two dimensionalstd::vectors
to represent matrices. - Use functions to implement the three different operations. Use references with proper constness to access
std::vectors
from functions. - You may assume that all input vector/matrices have non-zero dimensions, and that input will not contain values big enough to cause overflow.
Format:
The format to represent scalars/vectors/matrices in input/output is the following:
- A character among s, v and m to denote whether the data represent a scalar, a vector or a matrix (scalar cannot occur in input for this task).
-
A sequence of integers giving the dimensions of the value:
- Nothing for scalar
- A single integer giving the length for vectors
- Two integers giving respectively the number of rows and the number of columns for matrices
- A new line
-
A sequence of integers giving the content of the value:
- The scalar itself for scalars
- The content of the vector in order for vectors, on a single line
- The content of the matrix in row-major order for matrices (the content of the first row in column order first, then the second row, etc). Each row should be placed on a distinct line.
Note: Check io.h
and io.cpp
. The functions provided there can handle a large part of the input/output format.
Examples
Dot product of two 3D vectors
Left operand
v 3
1 2 3
Right operand
v 3
3 2 1
s
10
Multiply 3x2 matrix by 2D vector
Left operand
m 3 2
1 2
3 4
5 6
Right operand
v 2
2 1
v 3
4 10 16
Multiply 2x4 matrix 4x3 matrix
Left operand
m 2 4
1 2 3 4
5 6 7 8
Right operand
m 4 3
12 11 10
9 8 7
6 5 4
3 2 1
m 2 3
60 50 40
180 154 128
Multiply 2x3 matrix by 4D vector
Left operand
m 2 3
1 2 3
4 5 6
Right operand
v 4
4 3 2 1
error
Note: The scalar values should be returned only by scalar products. Even if a matrix-vector multiplication or a matrix-matrix multiplication results in a single value, it should be represented by a single-element vector or matrix. Similarly, if the result of a matrix-matrix multiplication looks like a vector, it should still be represented as a matrix, with one dimension equal to 1.
Solution
#include <iostream>
// Enable std::vectors
#include <vector>
#include "io.h"
using vec = std::vector<int>;
using mat = std::vector<vec>;
// POST: result of dot product of v1 and v2 is printed to standard output,
// or "error" if dimensions are not compatible
void vector_scalar_product(const vec& v, const int& s) {
vec res;
res = v;
for (unsigned long j = 0; j < v.size(); ++j)
res[j] = v[j] * s;
print_vector(res);
}
void matrix_scalar_product(const mat& m, const int& s) {
mat res;
res = m;
for (unsigned long j = 0; j < m.size(); ++j) {
for (unsigned long i = 0; i < m[0].size(); ++i)
res[j][i] = m[j][i] * s;
}
print_matrix(res);
}
void dot_product(const vec& v1, const vec& v2) {
int res = 0;
if (v1.size() == v2.size()) {
for (unsigned long j = 0; j < v1.size(); ++j)
res += (v1[j] * v2[j]);
print_scalar(res);
} else {
std::cout << "error";
}
}
void matrix_vector_product(const mat& m, const vec& v) {
vec res;
if (v.size() == m[0].size()) {
for (unsigned long j = 0; j < m.size(); ++j) {
int k = 0;
for (unsigned long i = 0; i < m[0].size(); ++i) {
k += m[j][i] * v[i];
}
res.push_back(k);
}
print_vector(res);
} else {
std::cout << "error";
}
}
void matrix_product(const mat& m1, const mat& m2) {
mat res(m1.size(), vec(m2[0].size()));
if (m1[0].size() == m2.size()) {
for (unsigned long i = 0; i < m1.size(); ++i) {
for (unsigned long j = 0; j < m2.size(); ++j) {
for (unsigned long k = 0; k < m2[0].size(); ++k) {
int l = m1[i][j] * m2[j][k];
res[i][k] += l;
}
}
}
print_matrix(res);
}
else {
std::cout << "error";
}
}
int main() {
std::cout << "Left operand" << std::endl;
char left_type;
std::cin >> left_type;
if (left_type == 'v') {
// left operand is vector
// get vector from input
vec left_operand;
read_vector(left_operand);
// get right operand type
std::cout << "Right operand" << std::endl;
char right_type;
std::cin >> right_type;
if (right_type == 's') {
// right operand is a scalar => compute scalar product
// get scalar from input
int s;
std::cin >> s;
// compute vector scalar product
vector_scalar_product(left_operand, s);
} else if (right_type == 'v') {
// right operand is a vector => compute dot product
// get vector from input
vec right_operand;
read_vector(right_operand);
// compute dot product
dot_product(left_operand, right_operand);
} else {
std::cout << "error";
}
} else if (left_type == 'm') {
// left operand is matrix
// get matrix from input
mat left_operand;
read_matrix(left_operand);
// get right operand type
std::cout << "Right operand" << std::endl;
char right_type;
std::cin >> right_type;
if (right_type == 's') {
// right operand is a scalar => compute scalar product
// get scalar from input
int s;
std::cin >> s;
// compute matrix scalar product
matrix_scalar_product(left_operand, s);
} else if (right_type == 'v') {
// right operand is a vector => compute dot product
// get vector from input
vec right_operand;
read_vector(right_operand);
// compute matrix vector product
matrix_vector_product(left_operand, right_operand);
} else if (right_type == 'm') {
// right operand is a matrix => compute matrix vector product
// get matrix from input
mat right_operand;
read_matrix(right_operand);
// compute matrix product
matrix_product(left_operand, right_operand);
} else {
std::cout << "error";
}
} else {
std::cout << "error";
}
return 0;
}
Made by JirR02 in Switzerland 🇨🇭