Commit 6de538d2 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

solution to exercise 5.3 added

parent f5f93321
......@@ -35,4 +35,23 @@ Matrix add(Matrix const& A, Matrix const& B)
}
return C;
}
\ No newline at end of file
}
/* alternative add implementation:
// Pass the first argument by value
Matrix add(Matrix A, Matrix const& B)
{
assert(A.rows.size() == B.rows.size());
for (std::size_t i = 0; i < A.rows.size(); ++i) {
assert(A.rows[i].size() == B.rows[i].size());
for (std::size_t j = 0; j < A.rows[i].size(); ++j) {
A.rows[i][j] += B.rows[i][j];
}
}
return A;
}
*/
\ No newline at end of file
// Compile this code and link against google benchmark suite
// g++ -O2 -DNDEBUG -isystem benchmark/include exercise3a.cc exercise3b.cc exercise3c.cc exercise3_benchmark.cc -o exercise3_benchmark -L benchmark/lib -lbenchmark -lpthread
#include <benchmark/benchmark.h>
#include "exercise3a.hh"
#include "exercise3b.hh"
#include "exercise3c.hh"
// Implementation of a (generic) test for full matrix insertion and adding
template <class Matrix>
void full_matrix()
{
const std::size_t size = 1000;
// matrix construction
Matrix lhs(1000,1000), rhs(1000,1000);
Matrix lhs(size,size), rhs(size,size);
// matrix initialization
std::srand(12345);
for (std::size_t i = 0; i < 1000; ++i) {
for (std::size_t j = 0; j < 1000; ++j) {
for (std::size_t i = 0; i < size; ++i) {
for (std::size_t j = 0; j < size; ++j) {
lhs(i,j) = 1 + std::rand() % 100;
rhs(i,j) = 1 + std::rand() % 100;
}
......@@ -23,17 +29,20 @@ void full_matrix()
lhs += rhs;
}
// Implementation of a (generic) test for sparse matrix insertion and adding
template <class Matrix>
void sparse_matrix()
{
const std::size_t size = 1000;
// matrix construction
Matrix lhs(1000,1000), rhs(1000,1000);
Matrix lhs(size,size), rhs(size,size);
// matrix initialization
std::srand(12345);
for (std::size_t n = 0; n < 1000; ++n) {
std::size_t i = std::rand() % 1000;
std::size_t j = std::rand() % 1000;
for (std::size_t n = 0; n < size; ++n) {
std::size_t i = std::rand() % size;
std::size_t j = std::rand() % size;
lhs(i,j) = 1 + std::rand() % 100;
rhs(i,j) = 1 + std::rand() % 100;
......@@ -44,6 +53,8 @@ void sparse_matrix()
}
// setting up all the benachmarks:
static void benchmark_full_matrix1(benchmark::State& state)
{
for (auto _ : state)
......
......@@ -3,13 +3,6 @@
#include "exercise3a.hh"
// Add the two matrices A and B and return the sum
Matrix1 operator+(Matrix1 lhs, Matrix1 const& rhs)
{
return lhs += rhs;
}
// NOTE:
// - default values for function parameters should not be repeated in the function definition.
// - in the constructor, all class members are (default) initialized, if not specified otherwise. Thus
......@@ -25,14 +18,14 @@ Matrix1::Matrix1(std::size_t r, std::size_t c, double value)
// NOTE:
// - assignment operators should always return a reference, since one wants to
// chain those operators, e.g. A += B += C += D ...
Matrix1& Matrix1::operator+=(Matrix1 const& B)
Matrix1& Matrix1::operator+=(Matrix1 const& rhs)
{
assert(rows.size() == B.rows.size());
assert(rows.size() == rhs.rows.size());
for (std::size_t i = 0; i < rows.size(); ++i) {
assert(rows[i].size() == B.rows[i].size());
assert(rows[i].size() == rhs.rows[i].size());
for (std::size_t j = 0; j < rows[i].size(); ++j) {
rows[i][j] += B.rows[i][j];
rows[i][j] += rhs.rows[i][j];
}
}
......
#pragma once
#include <cassert>
#include <vector>
......@@ -15,6 +17,7 @@ struct Matrix1
// Return the (i,j)th entry of the matrix
// NOTE:
// - implemented inline (keyword `inline` not necessary)
// - Functions with just 1 line could be implemented "inline" in the class
double access(std::size_t i, std::size_t j) const
{
......@@ -25,6 +28,7 @@ struct Matrix1
// NOTE: The only differences to the const access are
// 1. return type is reference
// 2. function is not const.
// NOTE: implemented inline (keyword `inline` not necessary)
double& access(std::size_t i, std::size_t j)
{
return rows[i][j];
......@@ -32,6 +36,7 @@ struct Matrix1
// Access by the bracket operator
// NOTE:
// - implemented inline (keyword `inline` not necessary)
// - The additional indirection by the call to `access` does not count, if
// that function is inlined by the compiler.
double operator()(std::size_t i, std::size_t j) const
......@@ -40,13 +45,14 @@ struct Matrix1
}
// An additional useful function is the *mutable* access to the data
// NOTE: implemented inline (keyword `inline` not necessary)
double& operator()(std::size_t i, std::size_t j)
{
return access(i,j);
}
// Accumulated plus operator
Matrix1& operator+=(Matrix1 const& B);
Matrix1& operator+=(Matrix1 const& rhs);
// The data of the matrix: row vectors
std::vector<std::vector<double>> rows;
......@@ -57,4 +63,8 @@ struct Matrix1
// - Here, the first argument is taken by value, since we need to create a copy anyway
// - An alternative signature would be (Matrix1 const& lhs, Matrix1 const& rhs)
// - Always try to implement the binary operators in terms of the compound assignment operators!
Matrix1 operator+(Matrix1 lhs, Matrix1 const& rhs);
// - keyword `inline` is necessary, since implemented in a header file
inline Matrix1 operator+(Matrix1 lhs, Matrix1 const& rhs)
{
return lhs += rhs;
}
......@@ -3,13 +3,6 @@
#include "exercise3b.hh"
// Add the two matrices A and B and return the sum
Matrix2 operator+(Matrix2 lhs, Matrix2 const& rhs)
{
return lhs += rhs;
}
// NOTE:
// - default values for function parameters should not be repeated in the function definition.
// - in the constructor, all class members are (default) initialized, if not specified otherwise. Thus
......
#pragma once
#include <cassert>
#include <vector>
......@@ -65,4 +67,7 @@ struct Matrix2
// - Here, the first argument is taken by value, since we need to create a copy anyway
// - An alternative signature would be (Matrix2 const& lhs, Matrix2 const& rhs)
// - Always try to implement the binary operators in terms of the compound assignment operators!
Matrix2 operator+(Matrix2 lhs, Matrix2 const& rhs);
inline Matrix2 operator+(Matrix2 lhs, Matrix2 const& rhs)
{
return lhs += rhs;
}
......@@ -3,13 +3,6 @@
#include "exercise3c.hh"
// Add the two matrices A and B and return the sum
Matrix3 operator+(Matrix3 lhs, Matrix3 const& rhs)
{
return lhs += rhs;
}
// NOTE:
// - in the constructor, all class members are (default) initialized, if not specified otherwise. Thus
// not clear of the rows is necessary
......
#pragma once
#include <cassert>
#include <map>
#include <tuple>
......@@ -67,4 +69,7 @@ struct Matrix3
// - Here, the first argument is taken by value, since we need to create a copy anyway
// - An alternative signature would be (Matrix3 const& lhs, Matrix3 const& rhs)
// - Always try to implement the binary operators in terms of the compound assignment operators!
Matrix3 operator+(Matrix3 lhs, Matrix3 const& rhs);
inline Matrix3 operator+(Matrix3 lhs, Matrix3 const& rhs)
{
return lhs += rhs;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment