Exercise 6
Added Exercise 6
This commit is contained in:
279
Informatik_I/Exercise_6/Task_4/README.org
Normal file
279
Informatik_I/Exercise_6/Task_4/README.org
Normal file
@@ -0,0 +1,279 @@
|
||||
#+TITLE: Task 4: Vector and matrix operations
|
||||
#+AUTHOR: JirR02
|
||||
|
||||
*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:
|
||||
|
||||
1. Dot product of two vectors (also called scalar product or inner product)
|
||||
1. Matrix-vector product (application of a matrix to a column vector)
|
||||
1. Matrix product
|
||||
|
||||
Implement the following program structure:
|
||||
|
||||
1. Query for the two operands from the input: the left operand first, then the right operand.
|
||||
1. If none of the three operators described above can be applied, output error then end the program.
|
||||
1. 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.
|
||||
1. Output the result of the operation then end the program.
|
||||
|
||||
Note: We already provide a partial implementation of this program in =main.cpp=.
|
||||
|
||||
*Recommendations:*
|
||||
|
||||
1. We provide functions to read and write matrices, vectors, and scalars in io.h. Use them!
|
||||
1. Use one dimensional =std::vectors= to represent vectors and two dimensional =std::vectors= to represent matrices.
|
||||
1. Use functions to implement the three different operations. Use references with proper constness to access =std::vectors= from functions.
|
||||
1. 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:
|
||||
|
||||
1. 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).
|
||||
2. A sequence of integers giving the dimensions of the value:
|
||||
a. Nothing for scalar
|
||||
b. A single integer giving the length for vectors
|
||||
c. Two integers giving respectively the number of rows and the number of columns for matrices
|
||||
3. A new line
|
||||
4. A sequence of integers giving the content of the value:
|
||||
a. The scalar itself for scalars
|
||||
b. The content of the vector in order for vectors, on a single line
|
||||
c. 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*
|
||||
|
||||
#+begin_src shell
|
||||
Left operand
|
||||
v 3
|
||||
1 2 3
|
||||
Right operand
|
||||
v 3
|
||||
3 2 1
|
||||
s
|
||||
10
|
||||
#+end_src
|
||||
|
||||
*Multiply 3x2 matrix by 2D vector*
|
||||
|
||||
#+begin_src shell
|
||||
Left operand
|
||||
m 3 2
|
||||
1 2
|
||||
3 4
|
||||
5 6
|
||||
Right operand
|
||||
v 2
|
||||
2 1
|
||||
v 3
|
||||
4 10 16
|
||||
#+end_src
|
||||
|
||||
*Multiply 2x4 matrix 4x3 matrix*
|
||||
|
||||
#+begin_src shell
|
||||
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
|
||||
#+end_src
|
||||
|
||||
*Multiply 2x3 matrix by 4D vector*
|
||||
|
||||
#+begin_src shell
|
||||
Left operand
|
||||
m 2 3
|
||||
1 2 3
|
||||
4 5 6
|
||||
Right operand
|
||||
v 4
|
||||
4 3 2 1
|
||||
error
|
||||
#+end_src
|
||||
|
||||
*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
|
||||
|
||||
#+begin_src cpp
|
||||
#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;
|
||||
}
|
||||
#+end_src
|
||||
|
||||
-----
|
||||
|
||||
Made by JirR02 in Switzerland 🇨🇭
|
Reference in New Issue
Block a user