init
This commit is contained in:
commit
96ff5392c8
11
exercise1/.clang-format
Normal file
11
exercise1/.clang-format
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
20
exercise1/.clangd
Normal file
20
exercise1/.clangd
Normal file
@ -0,0 +1,20 @@
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
5
exercise1/.ctests
Normal file
5
exercise1/.ctests
Normal file
@ -0,0 +1,5 @@
|
||||
task1_py
|
||||
task1_c
|
||||
task1_cpp
|
||||
task2
|
||||
task3
|
||||
5
exercise1/.expected-files
Normal file
5
exercise1/.expected-files
Normal file
@ -0,0 +1,5 @@
|
||||
info_python.txt
|
||||
info_c.txt
|
||||
info_cpp.txt
|
||||
task2.main.cpp
|
||||
task3.cpp
|
||||
16
exercise1/.gitattributes
vendored
Normal file
16
exercise1/.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
360
exercise1/.gitignore
vendored
Normal file
360
exercise1/.gitignore
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
# custom
|
||||
|
||||
*.csv
|
||||
*.png
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
4
exercise1/.gitmodules
vendored
Normal file
4
exercise1/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
59
exercise1/CMakeLists.txt
Normal file
59
exercise1/CMakeLists.txt
Normal file
@ -0,0 +1,59 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise3 LANGUAGES CXX C
|
||||
DESCRIPTION "exercise1"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise1")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED True)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||
add_test(NAME task1_py COMMAND ${Python3_EXECUTABLE} task1.test.py WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task1_c task1.test.c)
|
||||
add_test(NAME task1_c COMMAND task1_c WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task1_cpp task1.test.cpp)
|
||||
add_test(NAME task1_cpp COMMAND task1_cpp WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_custom_target(task1)
|
||||
add_dependencies(task1 task1_c task1_cpp)
|
||||
|
||||
add_executable(task2 task2.cpp)
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task2 PROPERTY PROPERTY_REGULAR_EXPRESSION "6633")
|
||||
|
||||
add_executable(task3 task3.cpp task3.test.cpp)
|
||||
add_test(NAME task3 COMMAND task3 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
19
exercise1/README.md
Normal file
19
exercise1/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Hausübung 1 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Donnerstag 7. März 2024, vormittags.
|
||||
|
||||
**Abgabe bis**: Montag 18. März 2024, Ende des Tages.
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise1`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- Konfiguration der benötigten Werkzeuge
|
||||
- Implementierung/Kompilierung/Ausführen eines lauffähigen Programms
|
||||
- Einfache Funktionen (ohne Bedingungen/Verzweigungen) mit Fundamentalen Typen als Parameter und Rückgabewert
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
1
exercise1/compile_flags.txt
Normal file
1
exercise1/compile_flags.txt
Normal file
@ -0,0 +1 @@
|
||||
-Imodules
|
||||
4
exercise1/info_python.txt
Normal file
4
exercise1/info_python.txt
Normal file
@ -0,0 +1,4 @@
|
||||
os: Windows 11 10.0.22631
|
||||
py: CPython 3.12.2
|
||||
np: numpy 1.26.4
|
||||
mpl: matplotlib 3.8.3
|
||||
204
exercise1/main.ipynb
Normal file
204
exercise1/main.ipynb
Normal file
@ -0,0 +1,204 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Konfigurieren und Testen der eigenen Umgebung (1 Punkt)\n",
|
||||
"\n",
|
||||
"1. Konfigurieren Sie Ihr eigenes System: https://sgit.iue.tuwien.ac.at/360050/setup\n",
|
||||
"\n",
|
||||
"2. Nachdem Sie Ihre Konfiguration abgeschlossen haben, testen Sie Ihre Konfiguration indem Sie folgenden drei mitgelieferte Tests ausführen:\n",
|
||||
"\n",
|
||||
"\t- [task1.test.py](task1.test.py) testet die Python-Konfiguration. \n",
|
||||
"\t- [task1.test.c](task1.test.c) testet die C-Konfiguration.\n",
|
||||
"\t- [task1.test.cpp](task1.test.cpp) testet die C++-Konfiguration."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Kompilieren/Ausführen \n",
|
||||
"\n",
|
||||
"Mittels manueller Aufrufe (`gcc/g++/python`):\n",
|
||||
"```shell\n",
|
||||
"# prepare folder\n",
|
||||
"mkdir build\n",
|
||||
"# compile for task1\n",
|
||||
"gcc -Imodules -std=c11 -g task1.test.c -o build/task1_c.exe\n",
|
||||
"g++ -Imodules -std=c++20 -g task1.test.cpp -o build/task1_cpp.exe\n",
|
||||
"# run tests for task1\n",
|
||||
"python task1.test.py # produces \"info_python.txt\"\n",
|
||||
"./build/task1_c.exe # produces \"info_c.txt\"\n",
|
||||
"./build/task1_cpp.exe # produces \"info_cpp.txt\"\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ mittels *CMake* (optional):\n",
|
||||
"```shell\n",
|
||||
"# prepare compilation\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile for task1\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"# run tests for task1\n",
|
||||
"ctest --test-dir build -C Debug -R task1\n",
|
||||
"```\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Ein eigenes kleines C++-Programm (1 Punkt)\n",
|
||||
"\n",
|
||||
"Erstellen Sie ein lauffähiges *Ein-Dateien-Programm* das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\t#include <iostream> // std::cout|endl\n",
|
||||
"\t#include <...>\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint sum(...){\n",
|
||||
"\t ...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion (Einstiegspunkt für jedes lauffähige Programm), die Ihre selbest geschriebene Funktion verwendet und die berechneten Ergebnisse in der Konsole ausgibt, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\n",
|
||||
"\t auto res = sum(...)\t\n",
|
||||
"\t std::cout << res << std::endl;\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` "
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [task2.main.cpp](task2.main.cpp)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [task2.main.cpp](task2.main.cpp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Kompilieren/Ausführen \n",
|
||||
"\n",
|
||||
"Mittels manueller Aufrufe (`gcc/g++/python`):\n",
|
||||
"```shell\n",
|
||||
"# prepare folder\n",
|
||||
"mkdir build\n",
|
||||
"# compile for task2\n",
|
||||
"g++ -std=c++20 -g task2.main.cpp -o build/task2.exe\n",
|
||||
"# run test (your output will be parsed when graded)\n",
|
||||
"./build/task2.exe\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ mittels *CMake* (optional):\n",
|
||||
"```shell\n",
|
||||
"# prepare compilation\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile for task2\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"# run tests for task2\n",
|
||||
"ctest --test-dir build -C Debug -R task2\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Einfache Funktionen ohne Verzweigungen (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie folgende Funktionen:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"double add(double x, double y, double z);\n",
|
||||
"double mul(double x, double y, double z);\n",
|
||||
"double frac(double x, double y);\n",
|
||||
"double mean(double x, double y, double z);\n",
|
||||
"double squared(double x);\n",
|
||||
"double cubed(double x);\n",
|
||||
"double eval(double x, double a, double b, double c);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklarationen und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.hpp`](task3.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task3.cpp`](task3.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.cpp`](task3.test.cpp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"#### Kompilieren/Ausführen \n",
|
||||
"\n",
|
||||
"Mittels manueller Aufrufe (`gcc/g++/python`):\n",
|
||||
"```shell\n",
|
||||
"# prepare folder\n",
|
||||
"mkdir build\n",
|
||||
"# compile for task3\n",
|
||||
"g++ -std=c++20 -g task3.cpp task3.test.cpp -o build/task3.exe\n",
|
||||
"# run test\n",
|
||||
"./build/task3.exe\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ mittels *CMake* (optional):\n",
|
||||
"```shell\n",
|
||||
"# prepare compilation\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile for task3\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"# run tests for task3\n",
|
||||
"ctest --test-dir build -C Debug -R task3\n",
|
||||
"```"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
1
exercise1/modules
Submodule
1
exercise1/modules
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b8ce24c87fc76396de465b2573e19909fd10cf13
|
||||
27
exercise1/task1.test.c
Normal file
27
exercise1/task1.test.c
Normal file
@ -0,0 +1,27 @@
|
||||
/// @file
|
||||
/// @brief Task1: tests (support for C11 standard)
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include <stdio.h> // FILE
|
||||
#include <stdlib.h> // EXIT_FAILURE|EXIT_SUCCESS
|
||||
|
||||
#include "iue-io/ccsv.h" // https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
|
||||
int main(void) {
|
||||
|
||||
FILE* stream = fopen("info_c.txt", "w");
|
||||
if (stream == NULL)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
fprintf(stream, "This compilation unit was compiled\n");
|
||||
fprintf(stream, " - on %s at %s\n", __DATE__, __TIME__);
|
||||
fprintf(stream, " - using the C language standard %li\n", __STDC_VERSION__);
|
||||
fprintf(stream, " - the main-function was present in this file: %s\n", __FILE__);
|
||||
fclose(stream);
|
||||
|
||||
assert(__STDC_VERSION__ >= 201112L);
|
||||
|
||||
printf("task1.test.c: all asserts passed\n");
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
35
exercise1/task1.test.cpp
Normal file
35
exercise1/task1.test.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/// @file
|
||||
/// @brief Task1: tests (support for C++20 standard)
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <filesystem> // std::filesystem::path
|
||||
#include <fstream> // std::ofstream
|
||||
#include <iostream> // std::cout|endl
|
||||
#include <sstream> // std::istringstream
|
||||
|
||||
#include <version> // https://en.cppreference.com/w/cpp/utility/feature_test
|
||||
|
||||
#include "iue-io/csv.hpp" // https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
|
||||
int main() {
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "This compilation unit was compiled" << std::endl;
|
||||
oss << " - on " << __DATE__ << " at " << __TIME__ << std::endl;
|
||||
oss << " - using the C++ language standard " << __cplusplus << std::endl;
|
||||
oss << " - the main-function was present in this file: " << __FILE__ << std::endl;
|
||||
|
||||
std::filesystem::path filename = "info_cpp.txt";
|
||||
std::ofstream ofs(filename);
|
||||
ofs.exceptions(std::ios::failbit);
|
||||
ofs << oss.str();
|
||||
|
||||
assert(__cplusplus >= 202002L);
|
||||
assert(__cpp_lib_filesystem >= 201703L);
|
||||
assert(__cpp_concepts >= 201907L);
|
||||
|
||||
std::cout << "task1.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
exercise1/task1.test.py
Normal file
49
exercise1/task1.test.py
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
""" Task1: tests (support for python, numpy and matplotlib) """
|
||||
|
||||
import platform
|
||||
|
||||
def os_info():
|
||||
""" Collects basic info on the operating system and logs it to a file 'os_info.txt'. """
|
||||
os_type = platform.system()
|
||||
os_rel = platform.release()
|
||||
os_ver = platform.version()
|
||||
return f"os: {os_type} {os_rel} {os_ver}\n"
|
||||
|
||||
def python_info():
|
||||
""" Obtains information on Python installation in use and logs it to a file 'python_info.txt'. """
|
||||
python_ver = platform.python_version()
|
||||
python_impl = platform.python_implementation()
|
||||
return f"py: {python_impl} {python_ver}\n"
|
||||
|
||||
import numpy
|
||||
|
||||
def numpy_info():
|
||||
""" Obtains information on the numpy package in use and logs it to a file 'numpy_info.txt'. """
|
||||
numpy_name = numpy.__name__
|
||||
numpy_ver = numpy.__version__
|
||||
return f"np: {numpy_name} {numpy_ver}\n"
|
||||
|
||||
import matplotlib
|
||||
|
||||
def matplotlib_info():
|
||||
""" Obtains information on the matplotlib package in use and logs it to a file 'matplotlib_info.txt'. """
|
||||
matplotlib_name = matplotlib.__name__
|
||||
matplotlib_ver = matplotlib.__version__
|
||||
return f"mpl: {matplotlib_name} {matplotlib_ver}\n"
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_python_env(self):
|
||||
with open("info_python.txt", "w") as f:
|
||||
f.write(os_info())
|
||||
f.write(python_info())
|
||||
f.write(numpy_info())
|
||||
f.write(matplotlib_info())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
25
exercise1/task2.cpp
Normal file
25
exercise1/task2.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/// @file
|
||||
/// @brief Task2: "single-file" excutable C++ program
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/// @brief Calculate the sum of two integer values
|
||||
/// @param a first integer value
|
||||
/// @param b second integer value
|
||||
/// @return Sum of the two integer values
|
||||
int sum(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
|
||||
/// @brief main function (entry point) conducting the following tasks in this order
|
||||
/// - create two local variables holding the integer values 33 and 6600
|
||||
/// - call your function 'sum' and provide the prepared variables as arguments to the call
|
||||
/// - capture the result of your function call in a local variable and print it to the console
|
||||
int main() {
|
||||
int a = 33;
|
||||
int b = 6600;
|
||||
int result = sum(a, b);
|
||||
std::cout << "The sum of " << a << " and " << b << " is " << result << std::endl;
|
||||
}
|
||||
65
exercise1/task3.cpp
Normal file
65
exercise1/task3.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/// @file
|
||||
/// @brief Task3: implementation
|
||||
|
||||
#include "task3.hpp" // add|mul|frac|mean|squared|cubed|eval
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
|
||||
/// @brief Calculates the sum of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Sum of the three values
|
||||
double add(double x, double y, double z) {
|
||||
return x+y+z;
|
||||
}
|
||||
|
||||
/// @brief Calculates the product of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Product of the three values
|
||||
double mul(double x, double y, double z) {
|
||||
return x*y*z;
|
||||
}
|
||||
|
||||
/// @brief Calculates the fraction of two values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @return Fraction of x divided by y
|
||||
double frac(double x, double y) {
|
||||
return x/y;
|
||||
}
|
||||
|
||||
/// @brief Calculates the average (arithmetic mean) of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Average of the three values
|
||||
double mean(double x, double y, double z) {
|
||||
return (x+y+z)/3;
|
||||
}
|
||||
|
||||
/// @brief Calculates the square of a value
|
||||
/// @param x Value
|
||||
/// @return Square of x
|
||||
double squared(double x) {
|
||||
return x*x;
|
||||
}
|
||||
|
||||
/// @brief Calculates the third power of a value
|
||||
/// @param x Value
|
||||
/// @return Cube of x
|
||||
double cubed(double x) {
|
||||
return x*x*x;
|
||||
}
|
||||
|
||||
/// @brief Evaluates a polynomial 'f(x) = a*x^2 + b*x + c'
|
||||
/// @param x Variable
|
||||
/// @param a Coefficient
|
||||
/// @param b Coefficient
|
||||
/// @param c Coefficient
|
||||
/// @return Value of the polynomial at x
|
||||
double eval(double x, double a, double b, double c) {
|
||||
return a*x*x + b*x + c;
|
||||
}
|
||||
49
exercise1/task3.hpp
Normal file
49
exercise1/task3.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/// @file
|
||||
/// @brief Task3: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
/// @brief Calculates the sum of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Sum of the three values
|
||||
double add(double x, double y, double z);
|
||||
|
||||
/// @brief Calculates the product of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Product of the three values
|
||||
double mul(double x, double y, double z);
|
||||
|
||||
/// @brief Calculates the fraction of two values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @return Fraction of x divided by y
|
||||
double frac(double x, double y);
|
||||
|
||||
/// @brief Calculates the average (arithmetic mean) of three values
|
||||
/// @param x 1st value
|
||||
/// @param y 2nd value
|
||||
/// @param z 3rd value
|
||||
/// @return Average of the three values
|
||||
double mean(double x, double y, double z);
|
||||
|
||||
/// @brief Calculates the square of a value
|
||||
/// @param x Value
|
||||
/// @return Square of x
|
||||
double squared(double x);
|
||||
|
||||
/// @brief Calculates the third power of a value
|
||||
/// @param x Value
|
||||
/// @return Cube of x
|
||||
double cubed(double x);
|
||||
|
||||
/// @brief Evaluates a polynomial 'f(x) = a*x^2 + b*x + c'
|
||||
/// @param x Variable
|
||||
/// @param a Coefficient
|
||||
/// @param b Coefficient
|
||||
/// @param c Coefficient
|
||||
/// @return Value of the polynomial at x
|
||||
double eval(double x, double a, double b, double c);
|
||||
44
exercise1/task3.test.cpp
Normal file
44
exercise1/task3.test.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/// @file
|
||||
/// @brief Test for Task3
|
||||
|
||||
#include "task3.hpp" // add|mul|frac|mean|squared|cubed|eval
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // std::abs
|
||||
#include <iostream> // std::cout|endl
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing function 'add'
|
||||
double res = add(1, 2, -3);
|
||||
assert(std::abs(res - 0.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'mul'
|
||||
double res = mul(2, 3, 4);
|
||||
assert(std::abs(res - 24.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'frac'
|
||||
double res = frac(1, 3);
|
||||
assert(std::abs(res - 1.0 / 3.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'mean'
|
||||
double res = mean(10, 90, -10);
|
||||
assert(std::abs(res - 30.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'squared'
|
||||
double res = squared(3);
|
||||
assert(std::abs(res - 9.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'cubed'
|
||||
double res = cubed(3);
|
||||
assert(std::abs(res - 27.0) < 1e-7);
|
||||
}
|
||||
{ // testing function 'cubed'
|
||||
double res = eval(10.0, 3, -30, 77);
|
||||
assert(std::abs(res - 77) < 1e-7);
|
||||
}
|
||||
|
||||
std::cout << "task3.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
exercise10/.clang-format
Normal file
10
exercise10/.clang-format
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
25
exercise10/.clangd
Normal file
25
exercise10/.clangd
Normal file
@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
3
exercise10/.ctests
Normal file
3
exercise10/.ctests
Normal file
@ -0,0 +1,3 @@
|
||||
task1
|
||||
task2
|
||||
task3
|
||||
3
exercise10/.expected-files
Normal file
3
exercise10/.expected-files
Normal file
@ -0,0 +1,3 @@
|
||||
task1.main.c
|
||||
task2.c
|
||||
task3.main.c
|
||||
16
exercise10/.gitattributes
vendored
Normal file
16
exercise10/.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
358
exercise10/.gitignore
vendored
Normal file
358
exercise10/.gitignore
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
# custom
|
||||
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
4
exercise10/.gitmodules
vendored
Normal file
4
exercise10/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
71
exercise10/CMakeLists.txt
Normal file
71
exercise10/CMakeLists.txt
Normal file
@ -0,0 +1,71 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise10 LANGUAGES C
|
||||
DESCRIPTION "exercise10"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise10")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED True)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# find math library and link to all targets
|
||||
|
||||
find_library(MATH_LIBRARY m)
|
||||
link_libraries(${MATH_LIBRARY})
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.c)
|
||||
target_link_libraries(task1 PRIVATE ${MATH_LIBRARY})
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION ".*10.*")
|
||||
|
||||
add_executable(task2 task2.c task2.test.c)
|
||||
target_link_libraries(task2 PRIVATE ${MATH_LIBRARY})
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3_main task2.c task3.main.c)
|
||||
|
||||
add_test(NAME task3_popt_fail COMMAND task3_main --left rrev4x4.csv --right matrix4x2.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_inpath_fail COMMAND task3_main --left hui.csv --right matrix4x2.csv --out result.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_dims_fail COMMAND task3_main --left matrix4x2.csv --right rrev4x4.csv --out result.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_outpath_fail COMMAND task3_main --left rrev4x4.csv --right matrix4x2.csv --out hui/result.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_csv_fail COMMAND task3_main --left rrev4x4.csv --right invalid.csv --out matrix4x2_rrow.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_rrow COMMAND task3_main --left rrev4x4.csv --right matrix4x2.csv --out matrix4x2_rrow.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
add_test(NAME task3_rcol COMMAND task3_main --left matrix4x2.csv --right rcol2x2.csv --out matrix4x2_rcols.csv WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3_test task3.test.c)
|
||||
add_test(NAME task3_test COMMAND task3_test WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
set_tests_properties(task3_popt_fail task3_inpath_fail task3_dims_fail task3_outpath_fail task3_csv_fail PROPERTIES WILL_FAIL TRUE)
|
||||
set_tests_properties(task3_test PROPERTIES DEPENDS task3_rrow)
|
||||
set_tests_properties(task3_test PROPERTIES DEPENDS task3_rcol)
|
||||
|
||||
add_custom_target(task3)
|
||||
add_dependencies(task3 task3_test task3_main)
|
||||
|
||||
19
exercise10/README.md
Normal file
19
exercise10/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Hausübung 10 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Donnerstag 6. Juni 2024, vormittags.
|
||||
|
||||
**Abgabe bis**: Montag 17. Juni 2024, Ende des Tages.
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise10`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- C: Kommandozeilen-Optionen
|
||||
- C: Speicherung multidimensionaler (hier zweidimensional) Felder in einem kontinuierlichen Speicherbereich (hier *row-major*-Ordnung)
|
||||
- C: Matrixoperationen basierend auf einer *row-major*-Ordnung
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
1
exercise10/compile_flags.txt
Normal file
1
exercise10/compile_flags.txt
Normal file
@ -0,0 +1 @@
|
||||
-Imodules
|
||||
5
exercise10/invalid.csv
Normal file
5
exercise10/invalid.csv
Normal file
@ -0,0 +1,5 @@
|
||||
// matrix4x2.csv: a 4x2 matrix, not using '#' to indicate comments, non float data
|
||||
not-a-number;11;12
|
||||
not-a-number;21;22
|
||||
not-a-number;31;32
|
||||
not-a-number;41;42
|
||||
|
203
exercise10/main.ipynb
Normal file
203
exercise10/main.ipynb
Normal file
@ -0,0 +1,203 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Ein eigenes kleines C-Programm (*row-major layout*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.c`](task1.main.c) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```c\n",
|
||||
"\t#include <limits.h> // INT_MAX\n",
|
||||
"\t#include <stdio.h> // printf\n",
|
||||
"\t...\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tsize_t func(...) {\n",
|
||||
"\t ...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion, die Ihre selbst geschriebene Funktion verwendet, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\t\n",
|
||||
"\t int res = func(...);\n",
|
||||
"\t ...\t\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.c`](task1.main.c)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.c`](task1.main.c)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Funktionalität für zweidimensionale Felder mit kontinuierlichem Speicherlayout (hier: *row-major order*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"\n",
|
||||
"Gegeben ist eine Struktur `struct Matrix`, die eine *M x N*-Matrix mit kontinuierlichem Speicherlayout darstellt, ebenso gegeben sind drei yugehörige Funktionen:<>\n",
|
||||
"```c\n",
|
||||
"struct Matrix {\n",
|
||||
" double* data; ///< pointer to a dynamically allocated contiguous memory block of size m*n\n",
|
||||
" size_t m; ///< number of rows (first dimension)\n",
|
||||
" size_t n; ///< number of colmns (second dimension)\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"struct Matrix matrix_init(size_t m, size_t n, const double *data);\n",
|
||||
"void matrix_print(const struct Matrix* mat);\n",
|
||||
"void matrix_clear(struct Matrix* mat);\n",
|
||||
"```\n",
|
||||
"Sie implementieren weitere vier Funktionen, die die Funktionalität erweitern:\n",
|
||||
"\n",
|
||||
"```c\n",
|
||||
"// todo: implement\n",
|
||||
"struct Matrix matrix_zeros(size_t m, size_t n);\n",
|
||||
"struct Matrix matrix_identity(size_t n);\n",
|
||||
"void matrix_transpose(struct Matrix* mat);\n",
|
||||
"void matrix_mult(const struct Matrix* a, const struct Matrix* b, struct Matrix* c);\n",
|
||||
"```\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Strukturen/Funktionen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.h`](task2.h)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.c`](task2.c)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.c`](task2.test.c) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Kommandozeilen-Programm Matrix/Matrix-Multiplikation (1 Punkt)\n",
|
||||
"\n",
|
||||
"Sie implementieren ein Programm, das \n",
|
||||
"\n",
|
||||
"- zwei Matrizen aus zwei `.csv`-Dateien einließt, \n",
|
||||
"- das Produkt der Matrizen berechnet (Matrix/Matrix-Multiplikation), und\n",
|
||||
"- das Ergebnis wiederum als `.csv`-Datei speichert.\n",
|
||||
"\n",
|
||||
"Die Dateinamen werden mittels der Kommandozeile übergeben.\n",
|
||||
"\n",
|
||||
"Das Programm bricht in folgenden Sitationen ab:\n",
|
||||
"\n",
|
||||
"- unzureichende Argumente\n",
|
||||
"- invalide Dateipfade\n",
|
||||
"- Fehler beim Einlesen der Dateien\n",
|
||||
"- inkompatible Matrix-Dimensionen"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.main.c`](task3.main.c)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task3.main.c`](task3.main.c)\n",
|
||||
"- Getestet wird Ihr Programm, indem es mit verschiedenen Parametern in der Kommandozeile aufgerufen wird (siehe auch [`CMakeLists.txt`](CMakeLists.txt) und im nächsten Abschnitt).\n",
|
||||
"- Nachfolgend werden die Ausgabedateien der letzten beiden Aufrufe mit den Tests in [`task3.test.c`](task3.test.c) überprüft."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `gcc`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"gcc -g -std=c11 task1.main.c -o build/task1 -lm\n",
|
||||
"gcc -g -Imodules -std=c11 task2.c task2.test.c -o build/task2 -lm\n",
|
||||
"gcc -g -Imodules -std=c11 task2.c task3.main.c -o build/task3_main -lm\n",
|
||||
"gcc -g -Imodules -std=c11 task3.test.c -o build/task3_test -lm\n",
|
||||
"\n",
|
||||
"# run tests\n",
|
||||
"./build/task1\n",
|
||||
"./build/task2\t\n",
|
||||
"./build/task3_main --left rrev4x4.csv --right matrix4x2.csv # expect runtime fail: invalid arguments\n",
|
||||
"./build/task3_main --left hui.csv --right matrix4x2.csv --out result.csv # expect runtime fail: invalid input filename\n",
|
||||
"./build/task3_main --left matrix4x2.csv --right rrev4x4.csv --out result.csv # expect runtime fail: invalid matrix dimensions\n",
|
||||
"./build/task3_main --left rrev4x4.csv --right matrix4x2.csv --out hui/result.csv # expect runtime fail: invalid output filename\n",
|
||||
"./build/task3_main --left rrev4x4.csv --right invalid.csv --out matrix4x2_rrow.csv # expect runtime fail: invalid line in invalid.csv\n",
|
||||
"./build/task3_main --left rrev4x4.csv --right matrix4x2.csv --out matrix4x2_rrow.csv # expected succeed and to generate matrix4x2_rrow.csv\n",
|
||||
"./build/task3_main --left matrix4x2.csv --right rcol2x2.csv --out matrix4x2_rcols.csv # expected succeed and to generate matrix4x2_rcols.csv\n",
|
||||
"./build/task3_test # tests the contents of the generated files matrix4x2_rrow.csv and matrix4x2_rcols.csv\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug # Windows\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -D CMAKE_C_FLAGS=\"-fsanitize=address\" # Linux\n",
|
||||
"# compile\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"cmake --build build --config Debug # all\n",
|
||||
"# run tests\n",
|
||||
"ctest --test-dir build -C Debug -R task1 --verbose\n",
|
||||
"ctest --test-dir build -C Debug -R task2 --verbose\n",
|
||||
"ctest --test-dir build -C Debug -R task3 --verbose\n",
|
||||
"ctest --test-dir build -C Debug # all\n",
|
||||
"``` \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
5
exercise10/matrix4x2.csv
Normal file
5
exercise10/matrix4x2.csv
Normal file
@ -0,0 +1,5 @@
|
||||
# matrix4x2.csv: a 4x2 matrix
|
||||
11;12
|
||||
21;22
|
||||
31;32
|
||||
41;42
|
||||
|
4
exercise10/matrix4x2_rcols.csv
Normal file
4
exercise10/matrix4x2_rcols.csv
Normal file
@ -0,0 +1,4 @@
|
||||
1.200000000000000000e+001;1.100000000000000000e+001
|
||||
2.200000000000000000e+001;2.100000000000000000e+001
|
||||
3.200000000000000000e+001;3.100000000000000000e+001
|
||||
4.200000000000000000e+001;4.100000000000000000e+001
|
||||
|
4
exercise10/matrix4x2_rrow.csv
Normal file
4
exercise10/matrix4x2_rrow.csv
Normal file
@ -0,0 +1,4 @@
|
||||
4.100000000000000000e+001;4.200000000000000000e+001
|
||||
3.100000000000000000e+001;3.200000000000000000e+001
|
||||
2.100000000000000000e+001;2.200000000000000000e+001
|
||||
1.100000000000000000e+001;1.200000000000000000e+001
|
||||
|
1
exercise10/modules
Submodule
1
exercise10/modules
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 33515ac3ade8381f1336333051f85c7f63c8705c
|
||||
3
exercise10/rcol2x2.csv
Normal file
3
exercise10/rcol2x2.csv
Normal file
@ -0,0 +1,3 @@
|
||||
# rcol2x2: reverses column order if right multiplied with any Mx2 matrix
|
||||
0; 1
|
||||
1; 0
|
||||
|
5
exercise10/rrev4x4.csv
Normal file
5
exercise10/rrev4x4.csv
Normal file
@ -0,0 +1,5 @@
|
||||
# rrev4x4.csv: reverses row order if left multiplied to a 4xN matrix
|
||||
0; 0; 0; 1
|
||||
0; 0; 1; 0
|
||||
0; 1; 0; 0
|
||||
1; 0; 0; 0
|
||||
|
67
exercise10/task1.main.c
Normal file
67
exercise10/task1.main.c
Normal file
@ -0,0 +1,67 @@
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" executable C program
|
||||
|
||||
/// @todo Include C standard library headers, as needed
|
||||
|
||||
/// @todo Implement a function 'max_column_sum' according to the description below:
|
||||
/// The function receives a "m x n"-matrix holding signed integer values stored in a contiguous block of memory using
|
||||
/// row-major layout. Specifically it receives these arguments
|
||||
/// - number of rows m
|
||||
/// - number of columns n
|
||||
/// - pointer to a contiguous block of memory containing m*n signed integer values
|
||||
/// - row-major storage order is used, access of element (i,j) -> data[j + n*i]
|
||||
/// The function then calculates the maximum column sum, i.e. the maximum sum of values in one column of the matrix, and
|
||||
/// returns this value.
|
||||
|
||||
/// @todo Implement a 'main' function conducting the following tasks in this order:
|
||||
/// - construct three local variables containing the following values:
|
||||
/// - an integer value for the number of rows: 2
|
||||
/// - an integer value for the number of columns: 4
|
||||
/// - an array of integer values to be interpreted as a 2x4 matrix in row-major layout containing these values:
|
||||
/// {5, -2, -12, 4, 1, 3, -5, 6}
|
||||
/// - use your function to calculate the maximum column sum of the 2x4 matrix specified by your three local variables
|
||||
/// - print the result to the console
|
||||
|
||||
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" executable C program
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/// Function to calculate the maximum column sum of a matrix
|
||||
int max_column_sum(int m, int n, int data[]) {
|
||||
int max_sum = data[0]; // Initialize with first element
|
||||
|
||||
// Loop through each column
|
||||
for (int j = 1; j < n; j++) {
|
||||
int current_sum = 0;
|
||||
// Loop through each row in the current column
|
||||
for (int i = 0; i < m; i++) {
|
||||
// Calculate sum of elements in current column
|
||||
current_sum += data[j + n * i];
|
||||
}
|
||||
// Update max_sum if current sum is greater
|
||||
if (current_sum > max_sum) {
|
||||
max_sum = current_sum;
|
||||
}
|
||||
}
|
||||
|
||||
return max_sum;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Define matrix dimensions
|
||||
int rows = 2;
|
||||
int cols = 4;
|
||||
|
||||
// Define matrix data in row-major order
|
||||
int data[] = {5, -2, -12, 4, 1, 3, -5, 6};
|
||||
|
||||
// Calculate maximum column sum
|
||||
int max_column_sum_value = max_column_sum(rows, cols, data);
|
||||
|
||||
// Print the result
|
||||
printf("Maximum column sum: %d\n", max_column_sum_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
102
exercise10/task2.c
Normal file
102
exercise10/task2.c
Normal file
@ -0,0 +1,102 @@
|
||||
/// @file
|
||||
/// @brief Task2: function definitions
|
||||
|
||||
#include "task2.h" // struct Matrix, matrix_mult
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
/// @todo Include C standard library headers as needed
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
struct Matrix matrix_init(size_t m, size_t n, const double* data) {
|
||||
struct Matrix res = {.data = malloc(sizeof(double) * m * n), .m = m, .n = n};
|
||||
double* A = res.data;
|
||||
for (size_t i = 0; i != m * n; ++i)
|
||||
A[i] = data[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
void matrix_print(const struct Matrix* mat) {
|
||||
size_t M = mat->m;
|
||||
size_t N = mat->n;
|
||||
const double* A = mat->data;
|
||||
|
||||
for (size_t m = 0; m != M; ++m) {
|
||||
for (size_t n = 0; n != N; ++n)
|
||||
printf("%lf ", A[n + N * m]);
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
void matrix_clear(struct Matrix* mat) {
|
||||
free(mat->data);
|
||||
mat->m = 0;
|
||||
mat->n = 0;
|
||||
}
|
||||
|
||||
/// @brief Initializes an matrix with zeros
|
||||
/// @param m first dimension of the matrix
|
||||
/// @param n first dimension of the matrix
|
||||
struct Matrix matrix_zeros(size_t m, size_t n){
|
||||
double* data = malloc(sizeof(double) * m * n);
|
||||
for (size_t i = 0; i != m * n; ++i)
|
||||
data[i] = 0;
|
||||
return matrix_init(m, n, data);
|
||||
}
|
||||
|
||||
/// @brief Initializes a square identity matrix
|
||||
/// @param n dimension of the identity matrix
|
||||
struct Matrix matrix_identity(size_t n){
|
||||
double* data = malloc(sizeof(double) * n * n);
|
||||
for (size_t i = 0; i != n; ++i)
|
||||
for (size_t j = 0; j != n; ++j)
|
||||
data[j + n * i] = i == j ? 1 : 0;
|
||||
return matrix_init(n, n, data);
|
||||
|
||||
}
|
||||
|
||||
/// @brief Transposes a matrix
|
||||
/// @param mat Matrix to be transposed
|
||||
/// @note this function might swap/replace the block of memory owned by the matrix
|
||||
void matrix_transpose(struct Matrix* mat){
|
||||
size_t m = mat->m;
|
||||
size_t n = mat->n;
|
||||
double* data = malloc(sizeof(double) * m * n);
|
||||
for (size_t i = 0; i != m; ++i)
|
||||
for (size_t j = 0; j != n; ++j)
|
||||
data[i + m * j] = mat->data[j + n * i];
|
||||
free(mat->data);
|
||||
mat->data = data;
|
||||
mat->m = n;
|
||||
mat->n = m;
|
||||
|
||||
}
|
||||
|
||||
/// @brief Performs a matrix-matrix mutliplication: a*b = c
|
||||
/// @a first matrix (left factor)
|
||||
/// @b second matrix (right factor)
|
||||
/// @c Result of the multiplication is stored in this Matrix:
|
||||
/// - the dimensions of this matrix must be 'a.m x b.n' when calling this function
|
||||
/// - the values will be overwritten with the result of the multiplication
|
||||
void matrix_mult(const struct Matrix* a, const struct Matrix* b, struct Matrix* c){
|
||||
size_t m = a->m;
|
||||
size_t n = a->n;
|
||||
size_t p = b->n;
|
||||
double* data = malloc(sizeof(double) * m * p);
|
||||
for (size_t i = 0; i != m; ++i)
|
||||
for (size_t j = 0; j != p; ++j){
|
||||
double sum = 0;
|
||||
for (size_t k = 0; k != n; ++k)
|
||||
sum += a->data[k + n * i] * b->data[j + p * k];
|
||||
data[j + p * i] = sum;
|
||||
}
|
||||
free(c->data);
|
||||
c->data = data;
|
||||
c->m = m;
|
||||
c->n = p;
|
||||
}
|
||||
51
exercise10/task2.h
Normal file
51
exercise10/task2.h
Normal file
@ -0,0 +1,51 @@
|
||||
/// @file
|
||||
/// @brief Task2: Structure definitions and function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
/// @brief Two-dimensional matrix with 'm' rows and 'n' columns.
|
||||
/// @note: the values ares stored in a contiguous block in memory in row-major layout
|
||||
/// @note: row-major storage order is used, access of element (i,j) -> data[j + n*i]
|
||||
struct Matrix {
|
||||
double* data; ///< pointer to a dynamically allocated contiguous memory block fitting m*n values
|
||||
size_t m; ///< number of rows (first dimension)
|
||||
size_t n; ///< number of columns (second dimension)
|
||||
};
|
||||
|
||||
/// @brief Initalize a matrix from the values in a buffer
|
||||
/// @param m first dimension of the matrix
|
||||
/// @param n second dimension of the matrix
|
||||
/// @param data contiguous memory holding the values to copy (in row-major format)
|
||||
struct Matrix matrix_init(size_t m, size_t n, const double* data);
|
||||
|
||||
/// @brief Prints a Matrix to the console
|
||||
/// @param mat Matrix to be printed
|
||||
void matrix_print(const struct Matrix* mat);
|
||||
|
||||
/// @brief Resets a matrix (deallocates memory and sets its size to 0 x 0)
|
||||
/// @param mat Matrix to be reset
|
||||
void matrix_clear(struct Matrix* mat);
|
||||
|
||||
/// @brief Initializes an matrix with zeros
|
||||
/// @param m first dimension of the matrix
|
||||
/// @param n first dimension of the matrix
|
||||
struct Matrix matrix_zeros(size_t m, size_t n);
|
||||
|
||||
/// @brief Initializes a square identity matrix
|
||||
/// @param n dimension of the identity matrix
|
||||
struct Matrix matrix_identity(size_t n);
|
||||
|
||||
/// @brief Transposes a matrix
|
||||
/// @param mat Matrix to be transposed
|
||||
/// @note this function might swap/replace the block of memory owned by the matrix
|
||||
void matrix_transpose(struct Matrix* mat);
|
||||
|
||||
/// @brief Performs a matrix-matrix mutliplication: a*b = c
|
||||
/// @a first matrix (left factor)
|
||||
/// @b second matrix (right factor)
|
||||
/// @c Result of the multiplication is stored in this Matrix:
|
||||
/// - the dimensions of this matrix must be 'a.m x b.n' when calling this function
|
||||
/// - the values will be overwritten with the result of the multiplication
|
||||
void matrix_mult(const struct Matrix* a, const struct Matrix* b, struct Matrix* c);
|
||||
220
exercise10/task2.test.c
Normal file
220
exercise10/task2.test.c
Normal file
@ -0,0 +1,220 @@
|
||||
/// @file
|
||||
/// @brief Task2: tests
|
||||
|
||||
#include "task2.h" // struct Matrix, matrix_mult
|
||||
|
||||
#include "modules/iue-num/numerics.h" // iuenum_isclose
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include <stdbool.h> // bool, true, false
|
||||
#include <stdio.h> // printf
|
||||
|
||||
// helper function
|
||||
bool isclose(const struct Matrix* a, const struct Matrix* b) {
|
||||
if (a->m != b->m)
|
||||
return false;
|
||||
if (a->n != b->n)
|
||||
return false;
|
||||
for (size_t i = 0; i != a->m; ++i)
|
||||
for (size_t j = 0; j != a->n; ++j)
|
||||
if (!iuenum_isclose(a->data[j + a->n * i], b->data[j + b->n * i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing 'matrix_zeros' for 3x3
|
||||
struct Matrix mat = matrix_zeros(3, 3);
|
||||
double data[3][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data[0][0]);
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_zeros' for 4x3
|
||||
struct Matrix mat = matrix_zeros(4, 3);
|
||||
double data[4][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 3, &data[0][0]);
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_identity' for 3x3
|
||||
|
||||
double data_expected[3][3] = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data_expected[0][0]);
|
||||
struct Matrix mat = matrix_identity(3);
|
||||
|
||||
// matrix_print(&mat);
|
||||
assert(isclose(&mat, &expected));
|
||||
// matrix_print(&expected);
|
||||
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_identity' for 4x4
|
||||
|
||||
double data_expected[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 4, &data_expected[0][0]);
|
||||
struct Matrix mat = matrix_identity(4);
|
||||
|
||||
// matrix_print(&mat);
|
||||
assert(isclose(&mat, &expected));
|
||||
// matrix_print(&expected);
|
||||
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_transpose' of a 3x3 identity
|
||||
|
||||
struct Matrix mat = matrix_identity(3);
|
||||
|
||||
double data_expected[3][3] = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data_expected[0][0]);
|
||||
|
||||
// matrix_print(&mat);
|
||||
matrix_transpose(&mat);
|
||||
// matrix_print(&mat);
|
||||
// matrix_print(&expected);
|
||||
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_transpose' for 4x2
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_expected[2][4] = {
|
||||
{11, 21, 31, 41},
|
||||
{12, 22, 32, 42},
|
||||
};
|
||||
struct Matrix expected = matrix_init(2, 4, &data_expected[0][0]);
|
||||
|
||||
// matrix_print(&mat);
|
||||
matrix_transpose(&mat);
|
||||
// matrix_print(&mat);
|
||||
// matrix_print(&expected);
|
||||
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_mult' using a left multiplty with a row permuting matrix
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_permute[4][4] = {
|
||||
{0, 0, 0, 1},
|
||||
{0, 0, 1, 0},
|
||||
{0, 1, 0, 0},
|
||||
{1, 0, 0, 0},
|
||||
};
|
||||
struct Matrix permute = matrix_init(4, 4, &data_permute[0][0]);
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{41, 42},
|
||||
{31, 32},
|
||||
{21, 22},
|
||||
{11, 12},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 2, &data_expected[0][0]);
|
||||
|
||||
struct Matrix product = matrix_zeros(permute.m, mat.n);
|
||||
|
||||
// matrix_print(&permute);
|
||||
// matrix_print(&mat);
|
||||
matrix_mult(&permute, &mat, &product); // left multiply with permuation matrix
|
||||
// matrix_print(&product);
|
||||
|
||||
assert(isclose(&product, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
matrix_clear(&permute);
|
||||
matrix_clear(&product);
|
||||
}
|
||||
|
||||
|
||||
{ // testing 'matrix_mult' using a right multiplty with a column permuting matrix
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_permute[2][2] = {
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
};
|
||||
struct Matrix permute = matrix_init(2, 2, &data_permute[0][0]);
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{12, 11},
|
||||
{22, 21},
|
||||
{32, 31},
|
||||
{42, 41},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 2, &data_expected[0][0]);
|
||||
|
||||
struct Matrix product = matrix_zeros(mat.m, permute.n);
|
||||
|
||||
// matrix_print(&permute);
|
||||
// matrix_print(&mat);
|
||||
matrix_mult(&mat, &permute, &product); // right multiply with permuation matrix
|
||||
// matrix_print(&product);
|
||||
|
||||
assert(isclose(&product, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
matrix_clear(&permute);
|
||||
matrix_clear(&product);
|
||||
}
|
||||
|
||||
printf("task2.test.c: all asserts passed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
196
exercise10/task3.main.c
Normal file
196
exercise10/task3.main.c
Normal file
@ -0,0 +1,196 @@
|
||||
/// @file
|
||||
/// @brief Task3: program with command line options
|
||||
|
||||
/// @todo Include header from modules/iue-*, as needed
|
||||
/// e.g. #include "iue-po/cpo.h"
|
||||
/// e.g. #include "iue-io/ccsv.h"
|
||||
|
||||
/// @todo Include header of task2, if needed
|
||||
// #include "task2.h"
|
||||
|
||||
/// @todo Include C standard library headers, as needed
|
||||
/// e.g. #include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
|
||||
|
||||
/// @todo Implement an executable program which the following top-level description:
|
||||
/// 1. reads two matrices 'L', and 'R' from two separate .csv-files
|
||||
/// 2. calculates the matrix product LR (i.e. a matrix-matrix multiplication)
|
||||
/// 3. stores the resulting matrix in a third .csv-file
|
||||
/// Detailed Requirements:
|
||||
/// 1. All .csv-files which are involved need to be compatible with
|
||||
/// the format supported by 'iueio_savetxt' and 'iueio_loadtxt' from the header 'iue-io/ccsv.h'
|
||||
/// using ';' as delimiter and '#' as comment
|
||||
/// 2. The program needs to support the following three mandatory command line arguments in arbitrary order:
|
||||
/// --left relative filepath to the 'L' matrix
|
||||
/// --right relative filepath to the 'R' matrix
|
||||
/// --out relative filepath for the produced result
|
||||
/// 3. The program prints an error message to stderr, terminates, and returns EXIT_FAILURE if
|
||||
/// a) If any of the mandatory arguments is missing
|
||||
/// b) If any of the provided filepaths is not valid
|
||||
/// c) If any of the provided files cannot be parsed successfully
|
||||
/// d) If the dimension of the provided matrices are not compatible
|
||||
/// 4. If the program finishes without any issue, it returns EXIT_SUCCESS
|
||||
///
|
||||
/// Implementation hints/valid assumtions for this exercise:
|
||||
/// - you do not need to support empty .csv-files
|
||||
/// - you can always assume that all rows in a .csv-file have the same length
|
||||
|
||||
/// @file
|
||||
/// @brief Task3: program with command line options
|
||||
|
||||
#include "modules/iue-io/ccsv.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#define DELIM ';'
|
||||
#define COMMENT '#'
|
||||
|
||||
// Function to multiply two matrices
|
||||
double** multiply_matrices(double** L, size_t L_rows, size_t L_cols, double** R, size_t R_rows, size_t R_cols, size_t* out_rows, size_t* out_cols) {
|
||||
if (L_cols != R_rows) {
|
||||
return NULL; // Incompatible dimensions
|
||||
}
|
||||
|
||||
*out_rows = L_rows;
|
||||
*out_cols = R_cols;
|
||||
|
||||
double** result = malloc(L_rows * sizeof(double*));
|
||||
for (size_t i = 0; i < L_rows; ++i) {
|
||||
result[i] = malloc(R_cols * sizeof(double));
|
||||
for (size_t j = 0; j < R_cols; ++j) {
|
||||
result[i][j] = 0.0;
|
||||
for (size_t k = 0; k < L_cols; ++k) {
|
||||
result[i][j] += L[i][k] * R[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char* left_filepath = NULL;
|
||||
char* right_filepath = NULL;
|
||||
char* out_filepath = NULL;
|
||||
bool left_set = false;
|
||||
bool right_set = false;
|
||||
bool out_set = false;
|
||||
|
||||
// Parse command line arguments
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--left") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "Missing argument for --left\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
left_filepath = argv[i + 1];
|
||||
left_set = true;
|
||||
i++;
|
||||
} else if (strcmp(argv[i], "--right") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "Missing argument for --right\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
right_filepath = argv[i + 1];
|
||||
right_set = true;
|
||||
i++;
|
||||
} else if (strcmp(argv[i], "--out") == 0) {
|
||||
if (i + 1 >= argc) {
|
||||
fprintf(stderr, "Missing argument for --out\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
out_filepath = argv[i + 1];
|
||||
out_set = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for missing mandatory arguments
|
||||
if (!left_set || !right_set || !out_set) {
|
||||
fprintf(stderr,
|
||||
"Missing mandatory arguments. Usage: %s --left <left_file.csv> --right <right_file.csv> --out "
|
||||
"<output_file.csv>\n",
|
||||
argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Load matrices from files
|
||||
struct Table left_table = {NULL, 0};
|
||||
struct Table right_table = {NULL, 0};
|
||||
if (iueio_loadtxt(left_filepath, &left_table, DELIM, COMMENT) != 0) {
|
||||
fprintf(stderr, "Error loading file %s\n", left_filepath);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (iueio_loadtxt(right_filepath, &right_table, DELIM, COMMENT) != 0) {
|
||||
fprintf(stderr, "Error loading file %s\n", right_filepath);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Check if the matrices are compatible
|
||||
//if (left_table.n == 0 || right_table.n == 0 || left_table.rows[0].n != right_table.rows[0].n) {
|
||||
// fprintf(stderr, "Incompatible dimensions\n");
|
||||
// return EXIT_FAILURE;
|
||||
//}
|
||||
|
||||
// Convert tables to matrices
|
||||
size_t L_rows = left_table.n;
|
||||
size_t L_cols = left_table.rows[0].n;
|
||||
double** L = malloc(L_rows * sizeof(double*));
|
||||
for (size_t i = 0; i < L_rows; ++i) {
|
||||
L[i] = malloc(L_cols * sizeof(double));
|
||||
for (size_t j = 0; j < L_cols; ++j) {
|
||||
L[i][j] = left_table.rows[i].values[j];
|
||||
}
|
||||
}
|
||||
|
||||
size_t R_rows = right_table.n;
|
||||
size_t R_cols = right_table.rows[0].n;
|
||||
double** R = malloc(R_rows * sizeof(double*));
|
||||
for (size_t i = 0; i < R_rows; ++i) {
|
||||
R[i] = malloc(R_cols * sizeof(double));
|
||||
for (size_t j = 0; j < R_cols; ++j) {
|
||||
R[i][j] = right_table.rows[i].values[j];
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply matrices
|
||||
size_t out_rows, out_cols;
|
||||
double** result = multiply_matrices(L, L_rows, L_cols, R, R_rows, R_cols, &out_rows, &out_cols);
|
||||
if (result == NULL) {
|
||||
fprintf(stderr, "Incompatible dimensions\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Convert result to table
|
||||
struct Table out_table = {NULL, 0};
|
||||
for (size_t i = 0; i < out_rows; ++i) {
|
||||
table_append_copy(&out_table, result[i], out_cols);
|
||||
}
|
||||
|
||||
// Save result to file
|
||||
if (iueio_savetxt(out_filepath, &out_table, DELIM, "", COMMENT) != 0) {
|
||||
fprintf(stderr, "Error saving file %s\n", out_filepath);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Free memory
|
||||
for (size_t i = 0; i < L_rows; ++i) {
|
||||
free(L[i]);
|
||||
}
|
||||
free(L);
|
||||
for (size_t i = 0; i < R_rows; ++i) {
|
||||
free(R[i]);
|
||||
}
|
||||
free(R);
|
||||
for (size_t i = 0; i < out_rows; ++i) {
|
||||
free(result[i]);
|
||||
}
|
||||
free(result);
|
||||
table_clear(&left_table);
|
||||
table_clear(&right_table);
|
||||
table_clear(&out_table);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
88
exercise10/task3.test.c
Normal file
88
exercise10/task3.test.c
Normal file
@ -0,0 +1,88 @@
|
||||
/// @file
|
||||
/// @brief Task3: tests of output files generated by other tests/commands using command line arguments for task3_main
|
||||
|
||||
#include "modules/iue-io/ccsv.h" // iueio_loadtxt
|
||||
#include "modules/iue-num/numerics.h" // iuenum_isclose
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include <stdbool.h> // bool, true, false
|
||||
#include <stdio.h> // printf
|
||||
|
||||
bool isclose(const struct Table* a, const struct Table* b) {
|
||||
if (a->n != b->n)
|
||||
return false;
|
||||
|
||||
for (size_t r = 0; r != a->n; ++r) {
|
||||
if (a->rows[r].n != a->rows[r].n)
|
||||
return false;
|
||||
for (size_t c = 0; c != a->rows[r].n; ++c)
|
||||
if (!iuenum_isclose(a->rows[r].values[c], b->rows[r].values[c]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing result of this command:
|
||||
// "./build/task3_main --left rrev4x4.csv --right matrix4x2.csv --out matrix4x2_rrow.csv"
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{41, 42},
|
||||
{31, 32},
|
||||
{21, 22},
|
||||
{11, 12},
|
||||
};
|
||||
|
||||
struct Table expected = {NULL, 0};
|
||||
table_append_copy(&expected, data_expected[0], 2);
|
||||
table_append_copy(&expected, data_expected[1], 2);
|
||||
table_append_copy(&expected, data_expected[2], 2);
|
||||
table_append_copy(&expected, data_expected[3], 2);
|
||||
|
||||
const char filepath[] = "matrix4x2_rrow.csv";
|
||||
struct Table table = {NULL, 0};
|
||||
|
||||
if (iueio_loadtxt(filepath, &table, ';', '#') != 0) {
|
||||
fprintf(stderr, "error loading file %s\n", filepath);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
assert(isclose(&table, &expected));
|
||||
table_clear(&table);
|
||||
table_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing result of this command:
|
||||
// "./build/task3_main --left matrix4x2.csv --right rcol2x2.csv --out matrix4x2_rcols.csv"
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{12, 11},
|
||||
{22, 21},
|
||||
{32, 31},
|
||||
{42, 41},
|
||||
};
|
||||
|
||||
struct Table expected = {NULL, 0};
|
||||
table_append_copy(&expected, data_expected[0], 2);
|
||||
table_append_copy(&expected, data_expected[1], 2);
|
||||
table_append_copy(&expected, data_expected[2], 2);
|
||||
table_append_copy(&expected, data_expected[3], 2);
|
||||
|
||||
const char filepath[] = "matrix4x2_rcols.csv";
|
||||
struct Table table = {NULL, 0};
|
||||
|
||||
if (iueio_loadtxt(filepath, &table, ';', '#') != 0) {
|
||||
fprintf(stderr, "error loading file %s\n", filepath);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
assert(isclose(&table, &expected));
|
||||
table_clear(&table);
|
||||
table_clear(&expected);
|
||||
}
|
||||
|
||||
printf("task3.test.c: all asserts passed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
11
exercise2/.clang-format
Normal file
11
exercise2/.clang-format
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
25
exercise2/.clangd
Normal file
25
exercise2/.clangd
Normal file
@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
3
exercise2/.ctests
Normal file
3
exercise2/.ctests
Normal file
@ -0,0 +1,3 @@
|
||||
task1
|
||||
task2
|
||||
task3
|
||||
3
exercise2/.expected-files
Normal file
3
exercise2/.expected-files
Normal file
@ -0,0 +1,3 @@
|
||||
task1.main.cpp
|
||||
task2.cpp
|
||||
task3.cpp
|
||||
16
exercise2/.gitattributes
vendored
Normal file
16
exercise2/.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
358
exercise2/.gitignore
vendored
Normal file
358
exercise2/.gitignore
vendored
Normal file
@ -0,0 +1,358 @@
|
||||
# custom
|
||||
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
42
exercise2/CMakeLists.txt
Normal file
42
exercise2/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise2 LANGUAGES CXX
|
||||
DESCRIPTION "exercise2"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise2")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.cpp)
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PROPERTY_REGULAR_EXPRESSION "-1024")
|
||||
|
||||
add_executable(task2 task2.cpp task2.test.cpp)
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3 task3.cpp task3.test.cpp)
|
||||
add_test(NAME task3 COMMAND task3 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
20
exercise2/README.md
Normal file
20
exercise2/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Hausübung 2 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Donnerstag 14. März 2024, vormittags.
|
||||
|
||||
**Abgabe bis**: Montag 08. April 2024, Ende des Tages.
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise2`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfließen:
|
||||
|
||||
- Bedingungen/Verzweigungen
|
||||
- Schleifen
|
||||
- Übergabe/Rückgabe/Manipulation von Sequenzen in Form eines `std::vector<int>` und `std::vector<double>`
|
||||
- Übergabe und Rückgabewerte mehrerer Werte mittels `std::tuple<double,double,double>` und `std::tuple<double,double>`
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
1
exercise2/compile_flags.txt
Normal file
1
exercise2/compile_flags.txt
Normal file
@ -0,0 +1 @@
|
||||
-Imodules
|
||||
2
exercise2/gitblah-sHB2
Normal file
2
exercise2/gitblah-sHB2
Normal file
@ -0,0 +1,2 @@
|
||||
2024-04-08T09:19:08+02:00 | b8f93888363b8ac94476d28a5f7e0b85485a23ec | who has two thumbs and is a genius? not this guy!
|
||||
2024-04-08T09:17:30+02:00 | 0d8d68a4679f8e4b48027a25da4280ec914cb6ab | Fingers crossed!
|
||||
192
exercise2/main.ipynb
Normal file
192
exercise2/main.ipynb
Normal file
@ -0,0 +1,192 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Cheatsheets\n",
|
||||
"\n",
|
||||
"- [exercise1](https://sgit.iue.tuwien.ac.at/360050/cheatsheet/raw/branch/master/exercise1.pdf)\n",
|
||||
"- [exercise2](https://sgit.iue.tuwien.ac.at/360050/cheatsheet/raw/branch/master/exercise2.pdf)\n",
|
||||
"\n",
|
||||
"## Aufgabe 1: Ein eigenes kleines C++-Programm (*vector in/ scalar out*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.cpp`](task1.main.cpp) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\t#include <iostream> // std::cout, std::endl\n",
|
||||
"\t#include <...>\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint func(...){\n",
|
||||
"\t ...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion (Einstiegspunkt für jedes lauffähige Programm), die Ihre selbst geschriebene Funktion verwendet und die berechneten Ergebnisse in der Konsole ausgibt, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\n",
|
||||
"\t auto res = func(...)\t\n",
|
||||
"\t std::cout << res << std::endl;\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.cpp`](task1.main.cpp)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.cpp`](task1.main.cpp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Funktion mit Sequenzen von Werten als Parameter (`std::vector`), internen Verzweigungen (`if`/`else`), und mehreren Rückgabewerten (`std::tuple`) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie die folgenden Funktionen:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"// type aliases\n",
|
||||
"using Vector = std::vector<double>;\n",
|
||||
"using Tuple2 = std::tuple<double,double>;\n",
|
||||
"\n",
|
||||
"int count_gt(Vector data, double ref);\n",
|
||||
"int count_lt(Vector data, double ref);\n",
|
||||
"\n",
|
||||
"Vector select_gt(Vector data, double ref);\n",
|
||||
"Vector select_lt(Vector data, double ref);\n",
|
||||
"Vector select_gt_and_lt(Vector data, double lower, double upper);\n",
|
||||
"\n",
|
||||
"double mean(Vector data);\n",
|
||||
"double median(Vector data);\n",
|
||||
"\n",
|
||||
"Tuple2 minmax(Vector data);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklarationen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.hpp`](task2.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.cpp`](task2.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.cpp`](task2.test.cpp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Kapselung einer Berechnung mittels einer Funktion mit mehreren Rückgabewerten (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Sie kapseln die Berechnung der Lösungen zu einer quadratischen Gleichung $ax^2 + bx + c = 0$ in einer Funktion.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Implementieren Sie folgenden beiden Funktionen (überladener Funktionsname):\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"std::tuple<double, double> solve_quadratic_equation(double a, double b, double c);\n",
|
||||
"std::tuple<double, double> solve_quadratic_equation(std::tuple<double, double, double> abc);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.hpp`](task3.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task3.cpp`](task3.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.cpp`](task3.test.cpp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `g++`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"g++ -g -std=c++20 task1.main.cpp -o build/task1.exe\n",
|
||||
"g++ -g -std=c++20 task2.cpp task2.test.cpp -o build/task2.exe\n",
|
||||
"g++ -g -std=c++20 task3.cpp task3.test.cpp -o build/task3.exe\n",
|
||||
"# run tests \n",
|
||||
"./build/task1.exe\n",
|
||||
"./build/task2.exe\n",
|
||||
"./build/task3.exe\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile \n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"# run tests \n",
|
||||
"ctest --test-dir build -C Debug -R task1\n",
|
||||
"ctest --test-dir build -C Debug -R task2\n",
|
||||
"ctest --test-dir build -C Debug -R task3\n",
|
||||
"```\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
33
exercise2/task1.main.cpp
Normal file
33
exercise2/task1.main.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" excutable C++ program
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/// @brief Find the minimum value in a sequence of integer values
|
||||
/// @param data Sequence of values stored in a std::vector<int> (assertion: sequence is not empty )
|
||||
/// @return Minimum value in the sequence
|
||||
int min(const std::vector<int>& data) {
|
||||
int min = data[0];
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
if (data[i] < min) {
|
||||
min = data[i];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/// @brief main function (entry point) conducting the following tasks in this order:
|
||||
/// - create and prepare a local variable of type std::vector<int>
|
||||
/// holding a sequence of 5 values in this order: -10, 20, 100, -1024, 2048
|
||||
/// - call your function 'min' and provide the prepared variable as argument to the call
|
||||
/// - capture the result of your function call in a local variable and print it to the console
|
||||
|
||||
int main() {
|
||||
std::vector<int> data = {-10, 20, 100, -1024, 2048};
|
||||
int min_value = min(data);
|
||||
std::cout << "The minimum value is: " << min_value << std::endl;
|
||||
return 0;
|
||||
}
|
||||
117
exercise2/task2.cpp
Normal file
117
exercise2/task2.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "task2.hpp" // count_gt|count_lt|select_gt|select_lt|select_gt_and_lt|mean|median|minmax
|
||||
#include <algorithm>
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
|
||||
/// @brief Counts how many values in a sequence are greater than (gt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Number of values in the sequence, which are greater than than ref
|
||||
int count_gt(std::vector<double> data, double ref) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (data[i] > ref) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// @brief Counts how many values in a sequence are less than (lt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Number of values in the sequence, which are less than than ref
|
||||
int count_lt(std::vector<double> data, double ref) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (data[i] < ref) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// @brief Selects values from a sequence which are greater than (gt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_gt(std::vector<double> data, double ref) {
|
||||
std::vector<double> selected;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (data[i] > ref) {
|
||||
selected.push_back(data[i]);
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
/// @brief Selects values from a sequence which are less than (lt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_lt(std::vector<double> data, double ref) {
|
||||
std::vector<double> selected;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (data[i] < ref) {
|
||||
selected.push_back(data[i]);
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
/// @brief Selects values from a sequence which are bounded by two reference values
|
||||
/// @param data Sequence of values
|
||||
/// @param lower Lower bound
|
||||
/// @param upper Upper bound
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_gt_and_lt(std::vector<double> data, double lower, double upper) {
|
||||
std::vector<double> selected;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
if (data[i] > lower && data[i] < upper) {
|
||||
selected.push_back(data[i]);
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
/// @brief Calculates the mean for a sequence of values
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Mean value (arithmetic mean)
|
||||
double mean(std::vector<double> data) {
|
||||
double sum = 0;
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
sum += data[i];
|
||||
}
|
||||
return sum / data.size();
|
||||
}
|
||||
|
||||
/// @brief Calculate the median for a sequence of numbers
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Median value:
|
||||
/// - if the length of the sequence is odd, the median value is "the middle value", else
|
||||
/// - if the length of the sequence is even, the median value is the avarage of the "two middle values"
|
||||
double median(std::vector<double> data) {
|
||||
std::sort(data.begin(), data.end());
|
||||
if (data.size() % 2 == 0) {
|
||||
return (data[data.size() / 2 - 1] + data[data.size() / 2]) / 2;
|
||||
} else {
|
||||
return data[data.size() / 2];
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Finds the minimum and maximum value
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Tuple with the minimum and maximum value (in this order)
|
||||
std::tuple<double, double> minmax(std::vector<double> data) {
|
||||
double min = data[0];
|
||||
double max = data[0];
|
||||
for (int i = 1; i < data.size(); i++) {
|
||||
if (data[i] < min) {
|
||||
min = data[i];
|
||||
}
|
||||
if (data[i] > max) {
|
||||
max = data[i];
|
||||
}
|
||||
}
|
||||
return std::make_tuple(min, max);
|
||||
}
|
||||
55
exercise2/task2.hpp
Normal file
55
exercise2/task2.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
/// @file
|
||||
/// @brief Task2: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple> // std::tuple
|
||||
#include <vector> // std::vector
|
||||
|
||||
/// @brief Counts how many values in a sequence are greater than (gt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Number of values in the sequence, which are greater than than ref
|
||||
int count_gt(std::vector<double> data, double ref);
|
||||
|
||||
/// @brief Counts how many values in a sequence are less than (lt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Number of values in the sequence, which are less than than ref
|
||||
int count_lt(std::vector<double> data, double ref);
|
||||
|
||||
/// @brief Selects values from a sequence which are greater than (gt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_gt(std::vector<double> data, double ref);
|
||||
|
||||
/// @brief Selects values from a sequence which are less than (lt) a reference value
|
||||
/// @param data Sequence of values
|
||||
/// @param ref Reference value
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_lt(std::vector<double> data, double ref);
|
||||
|
||||
/// @brief Selects values from a sequence which are bounded by two reference values
|
||||
/// @param data Sequence of values
|
||||
/// @param lower Lower bound
|
||||
/// @param upper Upper bound
|
||||
/// @return Sequence of selected (copied) values in the order of occurence in the original sequence
|
||||
std::vector<double> select_gt_and_lt(std::vector<double> data, double lower, double upper);
|
||||
|
||||
/// @brief Calculates the mean for a sequence of values
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Mean value (arithmetic mean)
|
||||
double mean(std::vector<double> data);
|
||||
|
||||
/// @brief Calculate the median for a sequence of numbers
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Median value:
|
||||
/// - if the length of the sequence is odd, the median value is "the middle value", else
|
||||
/// - if the length of the sequence is even, the median value is the avarage of the "two middle values"
|
||||
double median(std::vector<double> data);
|
||||
|
||||
/// @brief Finds the minimum and maximum value
|
||||
/// @param data Sequence of values; assertion: data.size() >= 1
|
||||
/// @return Tuple with the minimum and maximum value (in this order)
|
||||
std::tuple<double, double> minmax(std::vector<double> data);
|
||||
112
exercise2/task2.test.cpp
Normal file
112
exercise2/task2.test.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/// @file
|
||||
/// @brief Test for Task2
|
||||
|
||||
#include "task2.hpp" // count_gt|count_lt|select_gt|select_lt|select_gt_and_lt|mean|median|minmax
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <iostream> // std::cout|endl
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing function 'count_gt'
|
||||
int res = count_gt({1.0, 2.0, 3.0, 4.0}, 2.0);
|
||||
assert(res == 2);
|
||||
}
|
||||
|
||||
{ // testing function 'count_gt'
|
||||
int res = count_gt({-4.0, -2.0, -2.0, -1.0}, -2.0);
|
||||
assert(res == 1);
|
||||
}
|
||||
|
||||
{ // testing function 'count_lt'
|
||||
int res = count_lt({-4.0, -2.0, -2.0, -1.0}, -1.0);
|
||||
assert(res == 3);
|
||||
}
|
||||
|
||||
{ // testing function 'count_lt'
|
||||
int res = count_lt({2.0, 2.0, 2.0, 2.0}, 3.0);
|
||||
assert(res == 4);
|
||||
}
|
||||
|
||||
{ // testing function 'select_lt'
|
||||
std::vector<double> res = select_lt({2.0, 2.0, 2.0, 2.0}, 3.0);
|
||||
std::vector<double> expected = {2.0, 2.0, 2.0, 2.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'select_lt'
|
||||
std::vector<double> res = select_lt({1.0, 2.0, 3.0, 4.0}, 4.0);
|
||||
std::vector<double> expected = {1.0, 2.0, 3.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'select_gt'
|
||||
std::vector<double> res = select_gt({2.0, 2.0, 2.0, 2.0}, 2.0);
|
||||
std::vector<double> expected = {};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'select_gt'
|
||||
std::vector<double> res = select_gt({1.0, 2.0, 3.0, 4.0}, 2.0);
|
||||
std::vector<double> expected = {3.0, 4.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'select_gt_and_lt'
|
||||
std::vector<double> res = select_gt_and_lt({-3.0, 2.0, -3.0, -2.0, 4.0, 1.0, -1.0, -4.0}, -3.0, 3.0);
|
||||
std::vector<double> expected = {2.0, -2.0, 1.0, -1.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'mean'
|
||||
double res = mean({1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 0.0});
|
||||
double expected = 3.0;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'mean'
|
||||
double res = mean({-3.0, -2.0, -1.0, 1.0, 2.0, 3.0});
|
||||
double expected = 0.0;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'median'
|
||||
double res = median({3.0});
|
||||
double expected = 3.0;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'median'
|
||||
double res = median({2.0, 3.0});
|
||||
double expected = 2.5;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'median'
|
||||
double res = median({3.0, 2.0, 3.0, 2.0});
|
||||
double expected = 2.5;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'median'
|
||||
double res = median({3.0, 3.0, 3.0, -1.0, 4.0});
|
||||
double expected = 3.0;
|
||||
assert(std::abs(res - expected) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'minmax'
|
||||
std::tuple<double, double> res = minmax({300.0, 100.0});
|
||||
std::tuple<double, double> expected = {100.0, 300.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
{ // testing function 'minmax'
|
||||
std::tuple<double, double> res = minmax({-1.0, -2.0, -3.0, 4.0, 20.0, 12.0});
|
||||
std::tuple<double, double> expected = {-3.0, 20.0};
|
||||
assert(res == expected);
|
||||
}
|
||||
|
||||
std::cout << "task2.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
33
exercise2/task3.cpp
Normal file
33
exercise2/task3.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "task3.hpp" // solve_quadratic_equation
|
||||
#include <valarray>
|
||||
|
||||
/// @brief Calculates the real solutions of the quadratic equation a*x^2 + b*x + c = 0.
|
||||
/// @param a coefficient; assertion: 'a' is a non-zero value
|
||||
/// @param b coefficient
|
||||
/// @param c coefficient
|
||||
/// @return The two real solutions (order: ascending).
|
||||
/// If no real solutions exists, the tuple contains two quiet NaNs.
|
||||
std::tuple<double, double> solve_quadratic_equation(double a, double b, double c){
|
||||
double x1, x2;
|
||||
double d = b*b - 4*a*c;
|
||||
if(d < 0){
|
||||
x1 = NAN;
|
||||
x2 = NAN;
|
||||
}else{
|
||||
x1 = (-b - sqrt(d))/(2*a);
|
||||
x2 = (-b + sqrt(d))/(2*a);
|
||||
}
|
||||
return std::make_tuple(x1, x2);
|
||||
|
||||
}
|
||||
|
||||
/// @brief Calculates the real solutions of the quadratic equation a*x^2 + b*x + c = 0.
|
||||
/// @param abc coefficients; assertion: first coefficient 'a' is a non-zero value
|
||||
/// @return The two real solutions (order: ascending).
|
||||
/// If no real solutions exists, the tuple contains two quiet NaNs.
|
||||
std::tuple<double, double> solve_quadratic_equation(std::tuple<double, double, double> abc){
|
||||
double a = std::get<0>(abc);
|
||||
double b = std::get<1>(abc);
|
||||
double c = std::get<2>(abc);
|
||||
return solve_quadratic_equation(a, b, c);
|
||||
}
|
||||
20
exercise2/task3.hpp
Normal file
20
exercise2/task3.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
/// @file
|
||||
/// @brief Task3: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple> // std::tuple
|
||||
|
||||
/// @brief Calculates the real solutions of the quadratic equation a*x^2 + b*x + c = 0.
|
||||
/// @param a coefficient; assertion: 'a' is a non-zero value
|
||||
/// @param b coefficient
|
||||
/// @param c coefficient
|
||||
/// @return The two real solutions (order: ascending).
|
||||
/// If no real solutions exists, the tuple contains two quiet NaNs.
|
||||
std::tuple<double, double> solve_quadratic_equation(double a, double b, double c);
|
||||
|
||||
/// @brief Calculates the real solutions of the quadratic equation a*x^2 + b*x + c = 0.
|
||||
/// @param abc coefficients; assertion: first coefficient 'a' is a non-zero value
|
||||
/// @return The two real solutions (order: ascending).
|
||||
/// If no real solutions exists, the tuple contains two quiet NaNs.
|
||||
std::tuple<double, double> solve_quadratic_equation(std::tuple<double, double, double> abc);
|
||||
54
exercise2/task3.test.cpp
Normal file
54
exercise2/task3.test.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/// @file
|
||||
/// @brief Test for Task3
|
||||
|
||||
#include "task3.hpp" // solve_quadratic_equation
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // NAN
|
||||
#include <iostream> // std::cout|endl
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
auto [s1, s2] = solve_quadratic_equation(1.0, 3.0, 2.0);
|
||||
assert(std::abs(s1 - (-2.0)) < 1e-7);
|
||||
assert(std::abs(s2 - (-1.0)) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
std::tuple<double, double, double> coefficients = {1.0, 3.0, 2.0};
|
||||
auto [s1, s2] = solve_quadratic_equation(coefficients);
|
||||
assert(std::abs(s1 - (-2.0)) < 1e-7);
|
||||
assert(std::abs(s2 - (-1.0)) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
auto [s1, s2] = solve_quadratic_equation(1.0, 2.0, 5.0);
|
||||
assert(std::isnan(s1));
|
||||
assert(std::isnan(s2));
|
||||
}
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
std::tuple<double, double, double> coefficients = {1.0, 2.0, 5.0};
|
||||
auto [s1, s2] = solve_quadratic_equation(coefficients);
|
||||
assert(std::isnan(s1));
|
||||
assert(std::isnan(s2));
|
||||
}
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
auto [s1, s2] = solve_quadratic_equation(2.0, 1.0, -3.0);
|
||||
assert(std::abs(s1 - (-1.5)) < 1e-7);
|
||||
assert(std::abs(s2 - (1.0)) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function overloads 'solve_quadratic_equation'
|
||||
std::tuple<double, double, double> coefficients = {2.0, 1.0, -3.0};
|
||||
auto [s1, s2] = solve_quadratic_equation(coefficients);
|
||||
assert(std::abs(s1 - (-1.5)) < 1e-7);
|
||||
assert(std::abs(s2 - (1.0)) < 1e-7);
|
||||
}
|
||||
|
||||
std::cout << "task3.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
exercise3/.clang-format
Normal file
10
exercise3/.clang-format
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
25
exercise3/.clangd
Normal file
25
exercise3/.clangd
Normal file
@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
4
exercise3/.ctests
Normal file
4
exercise3/.ctests
Normal file
@ -0,0 +1,4 @@
|
||||
task1
|
||||
task2
|
||||
task3_cpp
|
||||
task3_py
|
||||
4
exercise3/.expected-files
Normal file
4
exercise3/.expected-files
Normal file
@ -0,0 +1,4 @@
|
||||
task1.main.cpp
|
||||
task2.cpp
|
||||
task3.cpp
|
||||
task3.py
|
||||
16
exercise3/.gitattributes
vendored
Normal file
16
exercise3/.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
360
exercise3/.gitignore
vendored
Normal file
360
exercise3/.gitignore
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
# custom
|
||||
|
||||
*.csv
|
||||
*.png
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
4
exercise3/.gitmodules
vendored
Normal file
4
exercise3/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
54
exercise3/CMakeLists.txt
Normal file
54
exercise3/CMakeLists.txt
Normal file
@ -0,0 +1,54 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise3 LANGUAGES CXX
|
||||
DESCRIPTION "exercise3"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise3")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.cpp)
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "45")
|
||||
|
||||
add_executable(task2 task2.cpp task2.test.cpp)
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3_cpp task2.cpp task3.cpp task3.test.cpp)
|
||||
add_test(NAME task3_cpp COMMAND task3_cpp WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||
add_test(NAME task3_py COMMAND ${Python3_EXECUTABLE} task3.test.py WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_tests_properties(task3_py PROPERTIES DEPENDS task3_cpp)
|
||||
|
||||
add_custom_target(task3)
|
||||
add_dependencies(task3 task3_cpp)
|
||||
|
||||
29
exercise3/README.md
Normal file
29
exercise3/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Hausübung 3 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Donnerstag 21. März 2024, vormittags.
|
||||
|
||||
**Abgabe bis**: Montag 15. April 2024, Ende des Tages.
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise3`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- Vektoren von Vektoren, hier beschränkt auf folgende Typen:
|
||||
```cpp
|
||||
std::vector<std::vector<double>>
|
||||
std::vector<std::vector<int>>
|
||||
```
|
||||
|
||||
- Uebergabe von aufrufbaren Objekten, mittels `std::function` hier beschränkt auf folgenden Typ:
|
||||
```cpp
|
||||
std::function<double(double)>
|
||||
```
|
||||
|
||||
- Numerische Integration und Differenzierung
|
||||
- Einbinden und Nutzung einer [lokalen Bibilothek](https://sgit.iue.tuwien.ac.at/360050/modules/src/branch/main/iue-io/csv.hpp) zum Schreiben von `.csv`-Dateien sowie Plotten der geschrieben Daten mit Python/Matplotlib.
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
1
exercise3/compile_flags.txt
Normal file
1
exercise3/compile_flags.txt
Normal file
@ -0,0 +1 @@
|
||||
-Imodules
|
||||
248
exercise3/main.ipynb
Normal file
248
exercise3/main.ipynb
Normal file
@ -0,0 +1,248 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Ein eigenes kleines C++-Programm (*vector of vectors*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.cpp`](task1.main.cpp) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\t#include <iostream> // std::cout, std::endl\n",
|
||||
"\t#include <...>\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint sum(...){\n",
|
||||
"\t ...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion (Einstiegspunkt für jedes lauffähige Programm), die Ihre selbest geschriebene Funktion verwendet und die berechneten Ergebnisse in der Konsole ausgibt, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\n",
|
||||
"\t auto res = sum(...)\t\n",
|
||||
"\t std::cout << res << std::endl;\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.cpp`](task1.main.cpp)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.cpp`](task1.main.cpp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Mathematische Funktionen abtasten, numerische Integration und Differenzierung (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Sie implementieren Funktionen, die\n",
|
||||
"\n",
|
||||
"- ein Intervall $[a,b]$ mittels $N$ Stellen gleichabständig abstasten -> $\\mathbf{x} = \\left[ x_1, x_2, ... , x_N \\right]$,\n",
|
||||
"- eine Funktion $f(x)$ für die diskreten Werte im Intervall evaluieren -> $\\mathbf{y} = \\left[ f(x_1), f(x_2), ... , f(x_N) \\right]$,\n",
|
||||
"- anhand der diskreten Wertepaare ($\\mathbf{x}, \\mathbf{y}$) die Ableitung approximieren:\n",
|
||||
"\t- Vorwärts-Differenz an der ersten Stelle: $f'(x_1) \\approx \\frac{y_2 - y_1}{x_2 - x_1}$,\n",
|
||||
"\t- Rückwarts-Differenz an der letzten Stelle: $f'(x_N) \\approx \\frac{y_N - y_{N-1}}{x_N - x_{N-1}}$,\n",
|
||||
"\t- Zentrale-Differenz für alle anderen Stellen $f'(x_i) \\approx \\frac{y_{i+1} - y_{i-1} }{x_{i+1} - x_{i-1}}$, und\n",
|
||||
"- anhand der diskreten Wertepaare ($\\mathbf{x}, \\mathbf{y}$) die Stammfunktion approximieren:\n",
|
||||
"\t- Integrationskonstante an der ersten Stelle: $F(x_1) = C$\n",
|
||||
"\t- Trapezregel für alle anderen Stellen: $F(x_i) \\approx C + \\sum_{2}^{i} \\left[ 0.5 \\cdot \\left(y_{i}+y_{i-1}\\right) \\cdot \\left(x_i - x_{i-1}\\right) \\right]$."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie die folgenden vier Funktionen:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"using Vector = std::vector<double>;\n",
|
||||
"using Callable = std::function<double(double)>;\n",
|
||||
"\n",
|
||||
"Vector range(double start, double end, unsigned int N);\n",
|
||||
"Vector sample(Vector values, Callable func);\n",
|
||||
"Vector numdiff(Vector x, Vector y);\n",
|
||||
"Vector numint(Vector x, Vector y, double C);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklarationen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.hpp`](task2.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.cpp`](task2.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.cpp`](task2.test.cpp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Diskrete Funktionswerte abspeichern und plotten (1 Punkt)\n",
|
||||
"\n",
|
||||
"Sie implementieren eine Funktion in C++ die eine `.csv`-Datei mit diskreten Funktionswerten erzeugt:\n",
|
||||
"- verwenden Sie Ihre in Aufgabe 2 entwickelten Funktionen zum Abtasten und numerisch Integrieren/Differenzieren\n",
|
||||
"- verwenden Sie die bereitgestellte Funktion [`iue::io::savetxt`](https://sgit.iue.tuwien.ac.at/360050/modules/src/commit/7b31b845bf2d1297553a8565ba6ca2474305394a/iue-io/csv.hpp#L20) zum Schreiben der `.csv`-Datei\n",
|
||||
"\n",
|
||||
"Ebenso implementieren Sie eine Funktion in Python, um die Funktionswerten in der von Ihnen erzeugten `.csv`-Datei zu plotten:\n",
|
||||
"- verwenden Sie [numpy.loadtxt](https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html) zum Lesen der `.csv`-Datei\n",
|
||||
"- verwenden Sie [`Matplotlib`](https://matplotlib.org/stable/tutorials/pyplot.html) zum Plotten der eingelesenen Daten"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie folgende Funktion (**C++**):\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"\n",
|
||||
"using Filename = std::filesystem::path;\n",
|
||||
"using Callable = std::function<double(double)>;\n",
|
||||
"\n",
|
||||
"void sample_to_csv(Filename filepath, \n",
|
||||
" char del, \n",
|
||||
" char comments, \n",
|
||||
" Callable func, \n",
|
||||
" double start, \n",
|
||||
" double end, \n",
|
||||
" unsigned int N);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.hpp`](task3.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task3.cpp`](task3.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.cpp`](task3.test.cpp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie zudem folgende Funktion (**Python**):\n",
|
||||
"\n",
|
||||
"```py\n",
|
||||
"def plot_discrete_function(csvfile, delimiter, comments, pngfile):\n",
|
||||
"\tpass # todo: implement\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Ihre Implementierung erfolgt in [`task3.py`](task3.py)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.py`](task3.test.py)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Die final erzeugten Plots könnten z.B. so aussehen:\n",
|
||||
"\n",
|
||||
" \n",
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `g++` und `python`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"g++ -g -std=c++20 task1.main.cpp -o build/task1.exe\n",
|
||||
"g++ -g -std=c++20 task2.cpp task2.test.cpp -o build/task2.exe\n",
|
||||
"g++ -g -Imodules -std=c++20 task2.cpp task3.cpp task3.test.cpp -o build/task3.exe\n",
|
||||
"\n",
|
||||
"# run tests\n",
|
||||
"./build/task1.exe\n",
|
||||
"./build/task2.exe\n",
|
||||
"./build/task3.exe\n",
|
||||
"python task3.test.py\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):s\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"cmake --build build --config Debug # all\n",
|
||||
"# run tests\n",
|
||||
"ctest --test-dir build -C Debug -R task1 \n",
|
||||
"ctest --test-dir build -C Debug -R task2 \n",
|
||||
"ctest --test-dir build -C Debug -R task3 \n",
|
||||
"ctest --test-dir build -C Debug # all\n",
|
||||
"``` \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
1
exercise3/modules
Submodule
1
exercise3/modules
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b8ce24c87fc76396de465b2573e19909fd10cf13
|
||||
38
exercise3/task1.main.cpp
Normal file
38
exercise3/task1.main.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" excutable C++ program
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
/// @brief Calculate the sum of all integer values in a std::vector<std::vector<int>>
|
||||
/// @param data A vector of vectors containing the values to be summed
|
||||
/// @return Sum of all values in data
|
||||
double sum(const std::vector<std::vector<int>>& data) {
|
||||
double sum = 0;
|
||||
for (const auto& row : data) {
|
||||
for (const auto& value : row) {
|
||||
sum += value;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/// @brief main function (entry point for executable) conducting the following tasks in this order
|
||||
/// - create and prepare a local variable of type std::vector<std::vector<int>>
|
||||
/// holding 9 int values in this arrangement:
|
||||
/// 1, 2, 3
|
||||
/// 4, 5, 6
|
||||
/// 7, 8, 9
|
||||
/// - call your function 'sum' and provide the prepared variable as argument to the call
|
||||
/// - capture the result of your function call in a local variable and print it to the console
|
||||
int main() {
|
||||
std::vector<std::vector<int>> data = {
|
||||
{1, 2, 3},
|
||||
{4, 5, 6},
|
||||
{7, 8, 9}
|
||||
};
|
||||
double result = sum(data);
|
||||
std::cout << "Sum: " << result << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
71
exercise3/task2.cpp
Normal file
71
exercise3/task2.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/// @file
|
||||
/// @brief Task2: implementation
|
||||
|
||||
#include "task2.hpp"
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
#include <cassert> // assert
|
||||
#include <functional> // std::function
|
||||
#include <vector> // std::vector
|
||||
#include <cmath> // std::abs
|
||||
|
||||
/// @brief Creates a sequence of equidistant values in a given interval (inclusive).
|
||||
/// @param start Start of the interval
|
||||
/// @param end End of the interval
|
||||
/// @param N Number of values; assumption: N >= 2
|
||||
/// @return Sequence of equidistant values in increasing order
|
||||
std::vector<double> range(double start, double end, unsigned int N) {
|
||||
assert(N >= 2);
|
||||
std::vector<double> values(N);
|
||||
double step = (end - start) / (N - 1);
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
values[i] = start + i * step;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/// @brief Evaluates a one-dimensional scalar function at the provided discrete locations
|
||||
/// @param values Sequence of discrete locations
|
||||
/// @param func Callable with a signature compatible with f(double) -> double
|
||||
/// @return Sequence of function values
|
||||
std::vector<double> sample(std::vector<double> values, std::function<double(double)> func) {
|
||||
std::vector<double> results(values.size());
|
||||
for (unsigned int i = 0; i < values.size(); ++i) {
|
||||
results[i] = func(values[i]);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/// @brief Performs a numerical differentiation using a combined forward/center/backward difference scheme
|
||||
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
||||
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
||||
/// @return Sequence of function values of the numerical derivative
|
||||
std::vector<double> numdiff(std::vector<double> x, std::vector<double> y) {
|
||||
assert(x.size() == y.size());
|
||||
assert(x.size() >= 2);
|
||||
std::vector<double> derivative(x.size());
|
||||
double h = x[1] - x[0];
|
||||
derivative[0] = (y[1] - y[0]) / h;
|
||||
for (unsigned int i = 1; i < x.size() - 1; ++i) {
|
||||
derivative[i] = (y[i + 1] - y[i - 1]) / (2 * h);
|
||||
}
|
||||
derivative[x.size() - 1] = (y[x.size() - 1] - y[x.size() - 2]) / h;
|
||||
return derivative;
|
||||
}
|
||||
|
||||
/// @brief Performs a numerical integration using the trapezoidal rule
|
||||
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
||||
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
||||
/// @param C Constant of integration
|
||||
/// @return Sequence of function values of the numerical antiderivative
|
||||
std::vector<double> numint(std::vector<double> x, std::vector<double> y, double C) {
|
||||
assert(x.size() == y.size());
|
||||
assert(x.size() >= 2);
|
||||
std::vector<double> integral(x.size());
|
||||
double h = x[1] - x[0];
|
||||
integral[0] = C;
|
||||
for (unsigned int i = 1; i < x.size(); ++i) {
|
||||
integral[i] = integral[i - 1] + (y[i - 1] + y[i]) * h / 2;
|
||||
}
|
||||
return integral;
|
||||
}
|
||||
34
exercise3/task2.hpp
Normal file
34
exercise3/task2.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
/// @file
|
||||
/// @brief Task2: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional> // std::function
|
||||
#include <vector> // std::vector
|
||||
|
||||
/// @brief Creates a sequence of equidistant values in a given interval (inclusive).
|
||||
/// @param start Start of the interval
|
||||
/// @param end End of the interval
|
||||
/// @param N Number of values; assumption: N >= 2
|
||||
/// @return Sequence of equidistant values in increasing order
|
||||
std::vector<double> range(double start, double end, unsigned int N);
|
||||
|
||||
/// @brief Evaluates a one-dimensional scalar function at the provided discrete locations
|
||||
/// @param values Sequence of discrete locations
|
||||
/// @param func Callable with a signature compatible with f(double) -> double
|
||||
/// @return Sequence of function values
|
||||
std::vector<double> sample(std::vector<double> values, std::function<double(double)> func);
|
||||
|
||||
/// @brief Performs a numerical differentiation using a combined forward/center/backward difference scheme
|
||||
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
||||
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
||||
/// @return Sequence of function values of the numerical derivative
|
||||
std::vector<double> numdiff(std::vector<double> x, std::vector<double> y);
|
||||
|
||||
/// @brief Performs a numerical integration using the trapezoidal rule
|
||||
/// @param x Discrete sequence of locations; assumption: two or more values, ascending, and equally spaced
|
||||
/// @param y Discrete sequence of function values; assumption: same size as 'x'
|
||||
/// @param C Constant of integration
|
||||
/// @return Sequence of function values of the numerical antiderivative
|
||||
std::vector<double> numint(std::vector<double> x, std::vector<double> y, double C);
|
||||
|
||||
97
exercise3/task2.test.cpp
Normal file
97
exercise3/task2.test.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/// @file
|
||||
/// @brief Task2: tests
|
||||
|
||||
#include "task2.hpp"
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // std::abs|sin
|
||||
#include <iostream> // std::cout|endl
|
||||
#include <vector> // std::vector
|
||||
|
||||
namespace help {
|
||||
|
||||
/// @brief only to disambiguate the 'sin'-overloads from cmath
|
||||
double sin(double value) { return std::sin(value); }
|
||||
|
||||
/// @brief only to disambiguate the 'cos'-overloads from cmath
|
||||
double cos(double value) { return std::cos(value); }
|
||||
|
||||
} // namespace help
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing function 'range'
|
||||
std::vector<double> x = range(0, 10, 11);
|
||||
|
||||
double dx = x[1] - x[0];
|
||||
assert(std::abs(dx - 1.0) < 1e-7);
|
||||
for (unsigned int i = 1; i != x.size(); ++i)
|
||||
assert(std::abs(x[i] - x[i - 1] - dx) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing functions 'range' and 'sample'
|
||||
std::vector<double> x = range(2, 10, 6);
|
||||
std::vector<double> f = sample(x, help::sin);
|
||||
for (unsigned int i = 0; i != x.size(); ++i)
|
||||
assert(std::abs(f[i] - help::sin(x[i])) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing functions 'range' and 'sample'
|
||||
std::vector<double> x = range(0, 5, 6);
|
||||
std::vector<double> f = sample(x, help::cos);
|
||||
for (unsigned int i = 0; i != x.size(); ++i)
|
||||
assert(std::abs(f[i] - help::cos(x[i])) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'numdiff'
|
||||
std::vector<double> x = {0, 1, 2, 3, 4};
|
||||
std::vector<double> f = {0, 1, 1, 1, 0.5};
|
||||
std::vector<double> df = numdiff(x, f);
|
||||
assert(std::abs(df[0] - 1.0) < 1e-7);
|
||||
assert(std::abs(df[1] - 0.5) < 1e-7);
|
||||
assert(std::abs(df[2] - 0.0) < 1e-7);
|
||||
assert(std::abs(df[3] + 0.25) < 1e-7);
|
||||
assert(std::abs(df[4] + 0.5) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'numdiff'
|
||||
double s = 2.0;
|
||||
std::vector<double> x = {0*s, 1*s, 2*s, 3*s, 4*s};
|
||||
std::vector<double> f = {0, 1, 1, 1, 0.5};
|
||||
std::vector<double> df = numdiff(x, f);
|
||||
assert(std::abs(df[0] - 1.00/s) < 1e-7);
|
||||
assert(std::abs(df[1] - 0.50/s) < 1e-7);
|
||||
assert(std::abs(df[2] - 0.00/s) < 1e-7);
|
||||
assert(std::abs(df[3] + 0.25/s) < 1e-7);
|
||||
assert(std::abs(df[4] + 0.50/s) < 1e-7);
|
||||
}
|
||||
|
||||
|
||||
{ // testing function 'numint'
|
||||
std::vector<double> x = {0, 1, 2, 3, 4};
|
||||
std::vector<double> f = {0, 1, 1, 1, 0};
|
||||
std::vector<double> F = numint(x, f, 0.0);
|
||||
assert(std::abs(F[0] - 0.0) < 1e-7);
|
||||
assert(std::abs(F[1] - (F[0] + 0.5)) < 1e-7);
|
||||
assert(std::abs(F[2] - (F[1] + 1.0)) < 1e-7);
|
||||
assert(std::abs(F[3] - (F[2] + 1.0)) < 1e-7);
|
||||
assert(std::abs(F[4] - (F[3] + 0.5)) < 1e-7);
|
||||
}
|
||||
|
||||
{ // testing function 'numint'
|
||||
double s = 2.0;
|
||||
std::vector<double> x = {0*s, 1*s, 2*s, 3*s, 4*s, 5*s};
|
||||
std::vector<double> f = {0, 1, 1, 1, 0, -1};
|
||||
std::vector<double> F = numint(x, f, 10.0);
|
||||
assert(std::abs(F[0] - 10.0) < 1e-7);
|
||||
assert(std::abs(F[1] - (F[0] + 0.5*s)) < 1e-7);
|
||||
assert(std::abs(F[2] - (F[1] + 1.0*s)) < 1e-7);
|
||||
assert(std::abs(F[3] - (F[2] + 1.0*s)) < 1e-7);
|
||||
assert(std::abs(F[4] - (F[3] + 0.5*s)) < 1e-7);
|
||||
assert(std::abs(F[5] - (F[4] - 0.5*s)) < 1e-7);
|
||||
}
|
||||
|
||||
std::cout << "task2.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
45
exercise3/task3.cpp
Normal file
45
exercise3/task3.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
/// @file
|
||||
/// @brief Task3: implementation
|
||||
|
||||
#include "task3.hpp" // sample_to_csv
|
||||
#include "iue-io/csv.hpp" // iue::io::savetxt
|
||||
#include "task2.hpp" // range|sample|numint|numdiff
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
#include <functional> // std::function
|
||||
#include <vector> // std::vector
|
||||
|
||||
/// @brief This function
|
||||
/// - samples a one-dimensional scalar function (f) in a provided interval and resolution,
|
||||
// - approximates its derivative (df) and antiderivative (F) numerically, and
|
||||
/// - produces a csv-file holding the discrete values in this form:
|
||||
/// - csv-column layout: x, f, F, df
|
||||
/// @param filepath
|
||||
/// @param del Delimiter
|
||||
/// @param comment Character designating a line as a comment
|
||||
/// @param func Callable with a signature compatible with f(double) -> double
|
||||
/// @param start Start of the interval
|
||||
/// @param end End of the interval
|
||||
/// @param N Number of values; assumption: N >= 2
|
||||
void sample_to_csv(std::filesystem::path filepath, char del, char comments, std::function<double(double)> func,
|
||||
double start, double end, unsigned int N) {
|
||||
// Create a sequence of equidistant values in the interval [start, end]
|
||||
std::vector<double> x = range(start, end, N);
|
||||
// Sample the function 'func' at the locations 'x'
|
||||
std::vector<double> f = sample(x, func);
|
||||
// Approximate the derivative of 'f' at the locations 'x'
|
||||
std::vector<double> df = numdiff(x, f);
|
||||
// Approximate the antiderivative of 'f' at the locations 'x'
|
||||
std::vector<double> F = numint(x, f, 0.0);
|
||||
// Create a matrix holding the discrete values of 'x', 'f', 'F', and 'df'
|
||||
std::vector<std::vector<double>> data(N, std::vector<double>(4));
|
||||
for (unsigned int i = 0; i < N; ++i) {
|
||||
data[i][0] = x[i];
|
||||
data[i][1] = f[i];
|
||||
data[i][2] = F[i];
|
||||
data[i][3] = df[i];
|
||||
}
|
||||
// Save the matrix to a csv-file
|
||||
iue::io::savetxt(filepath, data, del);
|
||||
|
||||
}
|
||||
22
exercise3/task3.hpp
Normal file
22
exercise3/task3.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
/// @file
|
||||
/// @brief Task3: function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem> // std::filesystem::path
|
||||
#include <functional> // std::function
|
||||
|
||||
/// @brief This function
|
||||
/// - samples a one-dimensional scalar function (f) in a provided interval and resolution,
|
||||
// - approximates its derivative (df) and antiderivative (F) numerically, and
|
||||
/// - produces a csv-file holding the discrete values in this form:
|
||||
/// - csv-column layout: x, f, F, df
|
||||
/// @param filepath
|
||||
/// @param del Delimiter
|
||||
/// @param comment Character designating a line as a comment
|
||||
/// @param func Callable with a signature compatible with f(double) -> double
|
||||
/// @param start Start of the interval
|
||||
/// @param end End of the interval
|
||||
/// @param N Number of values; assumption: N >= 2
|
||||
void sample_to_csv(std::filesystem::path filepath, char del, char comments, std::function<double(double)> func,
|
||||
double start, double end, unsigned int N);
|
||||
50
exercise3/task3.py
Normal file
50
exercise3/task3.py
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
""" Task3: implementation """
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def plot_discrete_function(csvfile, delimiter, comments, pngfile):
|
||||
"""
|
||||
Reads a csv-file containing discretized value of a function (f), its derivative (df) and antiderivative (F)
|
||||
and plots all three functions over the discrete value of the interval (x).
|
||||
|
||||
Expected csv-column layout:
|
||||
x, f, F, df
|
||||
|
||||
Requirements for the plot:
|
||||
- axis labels
|
||||
- a legend for the plotted data records
|
||||
|
||||
Implementation hints:
|
||||
- use numpy.loadtxt(...) for loading the data from the csvfile
|
||||
- use Matplotlib for plotting
|
||||
|
||||
Parameters
|
||||
----------
|
||||
csvfile : string
|
||||
Name of the csv-file containing the discrete function
|
||||
delimiter: character
|
||||
Charater used to delimit individual values in the rows
|
||||
comments: character
|
||||
Charater (when used as first character in a row) denoting comment lines
|
||||
pngfile : string
|
||||
Name of the file where the plot is saved
|
||||
"""
|
||||
# load data from csv file
|
||||
data = np.loadtxt(csvfile, delimiter=delimiter, comments=comments)
|
||||
x = data[:, 0]
|
||||
f = data[:, 1]
|
||||
F = data[:, 2]
|
||||
df = data[:, 3]
|
||||
|
||||
# plot the data
|
||||
plt.plot(x, f, label='f')
|
||||
plt.plot(x, F, label='F')
|
||||
plt.plot(x, df, label='df')
|
||||
plt.xlabel('x')
|
||||
plt.ylabel('y')
|
||||
plt.legend()
|
||||
plt.savefig(pngfile)
|
||||
plt.close('all')
|
||||
59
exercise3/task3.test.cpp
Normal file
59
exercise3/task3.test.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/// @file
|
||||
/// @brief Task3: tests
|
||||
|
||||
#include "task3.hpp"
|
||||
|
||||
#include "iue-io/csv.hpp"
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cmath> // std::sin
|
||||
#include <filesystem> // std::filesystem::remove
|
||||
#include <iostream> // std::cout|endl
|
||||
#include <numbers> // std::numbers::pi
|
||||
|
||||
int main() {
|
||||
|
||||
{
|
||||
auto f = [](double x) { return cos(x); };
|
||||
auto df = [](double x) { return -sin(x); };
|
||||
auto F = [](double x) { return sin(x) - (sin(0)); };
|
||||
std::filesystem::path filename = "test.task3.cos.csv";
|
||||
|
||||
std::filesystem::remove(filename);
|
||||
sample_to_csv(filename, ';', '#', f, 0, 2 * std::numbers::pi, 18);
|
||||
auto table = iue::io::loadtxt(filename, ';', '#');
|
||||
|
||||
assert(table.size() == 18);
|
||||
|
||||
for (unsigned int r = 0; r != table.size(); ++r) {
|
||||
assert(table[r].size() == 4);
|
||||
assert(std::abs(f(table[r][0]) - table[r][1]) < 0.2);
|
||||
assert(std::abs(F(table[r][0]) - table[r][2]) < 0.2);
|
||||
assert(std::abs(df(table[r][0]) - table[r][3]) < 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto f = [](double x) { return sin(x); };
|
||||
auto df = [](double x) { return cos(x); };
|
||||
auto F = [](double x) { return -cos(x) - (-cos(0)); };
|
||||
std::filesystem::path filename = "test.task3.sin.csv";
|
||||
|
||||
std::filesystem::remove(filename);
|
||||
sample_to_csv(filename, ';', '#', f, 0, 2 * std::numbers::pi, 360);
|
||||
auto table = iue::io::loadtxt(filename, ';', '#');
|
||||
|
||||
assert(table.size() == 360);
|
||||
|
||||
for (unsigned int r = 0; r != table.size(); ++r) {
|
||||
assert(table[r].size() == 4);
|
||||
assert(std::abs(f(table[r][0]) - table[r][1]) < 0.01);
|
||||
assert(std::abs(F(table[r][0]) - table[r][2]) < 0.01);
|
||||
assert(std::abs(df(table[r][0]) - table[r][3]) < 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "task3.test.cpp: all asserts passed" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
exercise3/task3.test.py
Normal file
39
exercise3/task3.test.py
Normal file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
""" Task3: tests """
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import matplotlib.pyplot as plt
|
||||
import task3
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test_plot_sin(self):
|
||||
|
||||
figname = "test.task3.sin.png"
|
||||
|
||||
if os.path.isfile(figname):
|
||||
os.remove(figname)
|
||||
|
||||
plt.close('all')
|
||||
task3.plot_discrete_function("test.task3.sin.csv",";","#",figname)
|
||||
plt.close('all')
|
||||
|
||||
self.assertTrue(os.path.isfile(figname))
|
||||
|
||||
def test_plot_cos(self):
|
||||
|
||||
figname = "test.task3.cos.png"
|
||||
|
||||
if os.path.isfile(figname):
|
||||
os.remove(figname)
|
||||
|
||||
plt.close('all')
|
||||
task3.plot_discrete_function("test.task3.cos.csv",";","#",figname)
|
||||
plt.close('all')
|
||||
|
||||
self.assertTrue(os.path.isfile(figname))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
10
exercise4/.clang-format
Normal file
10
exercise4/.clang-format
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
25
exercise4/.clangd
Normal file
25
exercise4/.clangd
Normal file
@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
3
exercise4/.ctests
Normal file
3
exercise4/.ctests
Normal file
@ -0,0 +1,3 @@
|
||||
task1
|
||||
task2
|
||||
task3
|
||||
3
exercise4/.expected-files
Normal file
3
exercise4/.expected-files
Normal file
@ -0,0 +1,3 @@
|
||||
task1.main.cpp
|
||||
task2.cpp
|
||||
task3.cpp
|
||||
16
exercise4/.gitattributes
vendored
Normal file
16
exercise4/.gitattributes
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
360
exercise4/.gitignore
vendored
Normal file
360
exercise4/.gitignore
vendored
Normal file
@ -0,0 +1,360 @@
|
||||
# custom
|
||||
|
||||
*.csv
|
||||
*.png
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
4
exercise4/.gitmodules
vendored
Normal file
4
exercise4/.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
50
exercise4/CMakeLists.txt
Normal file
50
exercise4/CMakeLists.txt
Normal file
@ -0,0 +1,50 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise4 LANGUAGES CXX
|
||||
DESCRIPTION "exercise4"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise4")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.cpp)
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-112|-1\\.120000e\\+02)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-221|-2\\.110000e\\+02)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(42|4\\.200000e\\+01)")
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "(-23|-2\\.300000e\\+01)")
|
||||
|
||||
add_executable(task2 task2.cpp task2.misc.cpp task2.test.cpp)
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3 task2.cpp task2.misc.cpp task3.cpp task3.misc.cpp task3.test.cpp)
|
||||
add_test(NAME task3 COMMAND task3 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
19
exercise4/README.md
Normal file
19
exercise4/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Hausübung 4 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Dienstag 16. April 2024, vormittags (Ursprünglich Donnerstag 11. April 2024).
|
||||
|
||||
**Abgabe bis**: Montag 29. April 2024, Ende des Tages. (Ursprünglich Montag 22. April)
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise4`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- Klassen mit ausschließlich öffentlichen Member Variablen (ohne benutzerdefinierte Konstruktoren)
|
||||
- Member Funktionen
|
||||
- Nutzung von selbst implementierter Funktionalität in einem separaten Anwendungskontext
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
1
exercise4/compile_flags.txt
Normal file
1
exercise4/compile_flags.txt
Normal file
@ -0,0 +1 @@
|
||||
-Imodules
|
||||
1145
exercise4/images/dusty_nikolaus_city.svg
Normal file
1145
exercise4/images/dusty_nikolaus_city.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 116 KiB |
265
exercise4/images/trains.svg
Normal file
265
exercise4/images/trains.svg
Normal file
@ -0,0 +1,265 @@
|
||||
<svg preserveAspectRatio='xMidYMid meet' version='1.1' xmlns='http://www.w3.org/2000/svg' viewbox='-16.9557 -3.85356 800 34.6821 ' height='34.682081' width='800.000000'>
|
||||
<g>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='1.54143,30.8285 1.54143,19.2678 0,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='18.1118,16.9557 16.185,14.6435 20.0385,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='41.6185,30.8285 41.6185,19.2678 40.0771,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='58.1888,16.9557 56.262,14.6435 60.1156,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='81.6956,30.8285 81.6956,19.2678 80.1541,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='98.2659,16.9557 96.3391,14.6435 100.193,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='121.773,30.8285 121.773,19.2678 120.231,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='138.343,16.9557 136.416,14.6435 140.27,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='161.85,30.8285 161.85,19.2678 160.308,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='178.42,16.9557 176.493,14.6435 180.347,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='201.927,30.8285 201.927,19.2678 200.385,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='218.497,16.9557 216.57,14.6435 220.424,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='242.004,30.8285 242.004,19.2678 240.462,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='258.574,16.9557 256.647,14.6435 260.501,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='282.081,30.8285 282.081,19.2678 280.539,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='298.651,16.9557 296.724,14.6435 300.578,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='322.158,30.8285 322.158,19.2678 320.617,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='338.728,16.9557 336.802,14.6435 340.655,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='362.235,30.8285 362.235,19.2678 360.694,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='378.805,16.9557 376.879,14.6435 380.732,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='402.312,30.8285 402.312,19.2678 400.771,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='418.882,16.9557 416.956,14.6435 420.809,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='442.389,30.8285 442.389,19.2678 440.848,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='458.96,16.9557 457.033,14.6435 460.886,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='482.466,30.8285 482.466,19.2678 480.925,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='499.037,16.9557 497.11,14.6435 500.963,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='522.543,30.8285 522.543,19.2678 521.002,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='539.114,16.9557 537.187,14.6435 541.04,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='562.62,30.8285 562.62,19.2678 561.079,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='579.191,16.9557 577.264,14.6435 581.118,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='602.697,30.8285 602.697,19.2678 601.156,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='619.268,16.9557 617.341,14.6435 621.195,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='642.775,30.8285 642.775,19.2678 641.233,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='659.345,16.9557 657.418,14.6435 661.272,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='682.852,30.8285 682.852,19.2678 681.31,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='699.422,16.9557 697.495,14.6435 701.349,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='722.929,30.8285 722.929,19.2678 721.387,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='739.499,16.9557 737.572,14.6435 741.426,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='763.006,30.8285 763.006,19.2678 761.464,25.0482 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='779.576,16.9557 777.649,14.6435 781.503,14.6435 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='1.54143,30.8285 38.5356,30.8285 38.5356,19.2678 1.54143,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='16.9557,19.2678 19.2678,19.2678 19.2678,15.4143 16.9557,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='30.8285,19.2678 38.5356,19.2678 38.5356,11.5607 30.8285,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='41.6185,30.8285 78.6127,30.8285 78.6127,19.2678 41.6185,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='57.0328,19.2678 59.3449,19.2678 59.3449,15.4143 57.0328,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='70.9056,19.2678 78.6127,19.2678 78.6127,11.5607 70.9056,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='81.6956,30.8285 118.69,30.8285 118.69,19.2678 81.6956,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='97.1098,19.2678 99.422,19.2678 99.422,15.4143 97.1098,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='110.983,19.2678 118.69,19.2678 118.69,11.5607 110.983,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='121.773,30.8285 158.767,30.8285 158.767,19.2678 121.773,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='137.187,19.2678 139.499,19.2678 139.499,15.4143 137.187,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='151.06,19.2678 158.767,19.2678 158.767,11.5607 151.06,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='161.85,30.8285 198.844,30.8285 198.844,19.2678 161.85,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='177.264,19.2678 179.576,19.2678 179.576,15.4143 177.264,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='191.137,19.2678 198.844,19.2678 198.844,11.5607 191.137,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='201.927,30.8285 238.921,30.8285 238.921,19.2678 201.927,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='217.341,19.2678 219.653,19.2678 219.653,15.4143 217.341,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='231.214,19.2678 238.921,19.2678 238.921,11.5607 231.214,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='242.004,30.8285 278.998,30.8285 278.998,19.2678 242.004,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='257.418,19.2678 259.73,19.2678 259.73,15.4143 257.418,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='271.291,19.2678 278.998,19.2678 278.998,11.5607 271.291,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='282.081,30.8285 319.075,30.8285 319.075,19.2678 282.081,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='297.495,19.2678 299.807,19.2678 299.807,15.4143 297.495,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='311.368,19.2678 319.075,19.2678 319.075,11.5607 311.368,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='322.158,30.8285 359.152,30.8285 359.152,19.2678 322.158,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='337.572,19.2678 339.884,19.2678 339.884,15.4143 337.572,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='351.445,19.2678 359.152,19.2678 359.152,11.5607 351.445,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='362.235,30.8285 399.229,30.8285 399.229,19.2678 362.235,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='377.649,19.2678 379.961,19.2678 379.961,15.4143 377.649,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='391.522,19.2678 399.229,19.2678 399.229,11.5607 391.522,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='402.312,30.8285 439.306,30.8285 439.306,19.2678 402.312,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='417.726,19.2678 420.039,19.2678 420.039,15.4143 417.726,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='431.599,19.2678 439.306,19.2678 439.306,11.5607 431.599,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='442.389,30.8285 479.383,30.8285 479.383,19.2678 442.389,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='457.803,19.2678 460.116,19.2678 460.116,15.4143 457.803,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='471.676,19.2678 479.383,19.2678 479.383,11.5607 471.676,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='482.466,30.8285 519.461,30.8285 519.461,19.2678 482.466,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='497.881,19.2678 500.193,19.2678 500.193,15.4143 497.881,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='511.753,19.2678 519.461,19.2678 519.461,11.5607 511.753,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='522.543,30.8285 559.538,30.8285 559.538,19.2678 522.543,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='537.958,19.2678 540.27,19.2678 540.27,15.4143 537.958,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='551.83,19.2678 559.538,19.2678 559.538,11.5607 551.83,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='562.62,30.8285 599.615,30.8285 599.615,19.2678 562.62,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='578.035,19.2678 580.347,19.2678 580.347,15.4143 578.035,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='591.908,19.2678 599.615,19.2678 599.615,11.5607 591.908,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='602.697,30.8285 639.692,30.8285 639.692,19.2678 602.697,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='618.112,19.2678 620.424,19.2678 620.424,15.4143 618.112,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='631.985,19.2678 639.692,19.2678 639.692,11.5607 631.985,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='642.775,30.8285 679.769,30.8285 679.769,19.2678 642.775,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='658.189,19.2678 660.501,19.2678 660.501,15.4143 658.189,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='672.062,19.2678 679.769,19.2678 679.769,11.5607 672.062,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='682.852,30.8285 719.846,30.8285 719.846,19.2678 682.852,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='698.266,19.2678 700.578,19.2678 700.578,15.4143 698.266,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='712.139,19.2678 719.846,19.2678 719.846,11.5607 712.139,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='722.929,30.8285 759.923,30.8285 759.923,19.2678 722.929,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='738.343,19.2678 740.655,19.2678 740.655,15.4143 738.343,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='752.216,19.2678 759.923,19.2678 759.923,11.5607 752.216,11.5607 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='763.006,30.8285 800,30.8285 800,19.2678 763.006,19.2678 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='778.42,19.2678 780.732,19.2678 780.732,15.4143 778.42,15.4143 '/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='792.293,19.2678 800,19.2678 800,11.5607 792.293,11.5607 '/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='5.780347'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='10.404624'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='16.955684'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='25.433526'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='33.911368'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='16.955684'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='19.267823'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='21.579961'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='45.857418'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='50.481696'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='57.032755'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='65.510597'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='73.988439'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='57.032755'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='59.344894'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='61.657033'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='85.934489'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='90.558767'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='97.109827'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='105.587669'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='114.065511'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='97.109827'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='99.421965'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='101.734104'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='126.011561'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='130.635838'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='137.186898'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='145.664740'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='154.142582'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='137.186898'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='139.499037'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='141.811175'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='166.088632'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='170.712909'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='177.263969'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='185.741811'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='194.219653'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='177.263969'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='179.576108'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='181.888247'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='206.165703'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='210.789981'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='217.341040'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='225.818882'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='234.296724'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='217.341040'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='219.653179'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='221.965318'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='246.242775'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='250.867052'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='257.418112'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='265.895954'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='274.373796'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='257.418112'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='259.730250'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='262.042389'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='286.319846'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='290.944123'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='297.495183'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='305.973025'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='314.450867'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='297.495183'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='299.807322'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='302.119461'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='326.396917'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='331.021195'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='337.572254'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='346.050096'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='354.527938'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='337.572254'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='339.884393'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='342.196532'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='366.473988'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='371.098266'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='377.649326'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='386.127168'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='394.605010'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='377.649326'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='379.961464'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='382.273603'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='406.551060'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='411.175337'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='417.726397'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='426.204239'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='434.682081'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='417.726397'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='420.038536'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='422.350674'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='446.628131'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='451.252408'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='457.803468'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='466.281310'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='474.759152'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='457.803468'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='460.115607'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='462.427746'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='486.705202'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='491.329480'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='497.880539'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='506.358382'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='514.836224'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='497.880539'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='500.192678'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='502.504817'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='526.782274'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='531.406551'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='537.957611'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='546.435453'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='554.913295'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='537.957611'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='540.269750'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='542.581888'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='566.859345'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='571.483622'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='578.034682'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='586.512524'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='594.990366'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='578.034682'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='580.346821'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='582.658960'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='606.936416'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='611.560694'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='618.111753'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='626.589595'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='635.067437'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='618.111753'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='620.423892'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='622.736031'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='647.013487'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='651.637765'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='658.188825'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='666.666667'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='675.144509'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='658.188825'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='660.500963'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='662.813102'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='687.090559'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='691.714836'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='698.265896'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='706.743738'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='715.221580'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='698.265896'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='700.578035'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='702.890173'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='727.167630'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='731.791908'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='738.342967'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='746.820809'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='755.298651'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='738.342967'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='740.655106'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='742.967245'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='767.244701'/>
|
||||
<circle fill='none' stroke='black' r='1.926782' cy='32.755299' stroke-width='1' cx='771.868979'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='778.420039'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='786.897881'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='30.828516' stroke-width='1' cx='795.375723'/>
|
||||
<circle fill='none' stroke='black' r='0.770713' cy='13.102119' stroke-width='1' cx='778.420039'/>
|
||||
<circle fill='none' stroke='black' r='1.541426' cy='10.019268' stroke-width='1' cx='780.732177'/>
|
||||
<circle fill='none' stroke='black' r='3.853565' cy='3.853565' stroke-width='1' cx='783.044316'/>
|
||||
<polygon fill='none' stroke='black' stroke-width='1' points='0,34.6821 800,34.6821 800,0 0,0 '/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
256
exercise4/main.ipynb
Normal file
256
exercise4/main.ipynb
Normal file
@ -0,0 +1,256 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Ein eigenes kleines C++-Programm (*coordinate rotation*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.cpp`](task1.main.cpp) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\t#include <array> // std::array\n",
|
||||
"\t#include <cmath> // std::sin, std::cos\n",
|
||||
"\t#include <iostream> // std::cout, std::endl\n",
|
||||
"\t#include <numbers> // std::numbers::pi\n",
|
||||
"\t...\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion in einem eignene Namensraum, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tnamespace task1 {\n",
|
||||
"\n",
|
||||
"\tusing Coord = std::array<double, 2>;\n",
|
||||
"\n",
|
||||
"\tCoord rotate_counter_clockwise(Coord coord, double angle) {\n",
|
||||
"\t\t...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion, die Ihre selbst geschriebene Funktion verwendet und die berechneten Ergebnisse in der Konsole ausgibt, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\n",
|
||||
"\t auto [xrot, yrot] = rotate_counter_clockwise(...)\t\n",
|
||||
"\t std::cout << xrot << \" \" << yrot << std::endl;\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.cpp`](task1.main.cpp)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.cpp`](task1.main.cpp)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Member Funktionen und Klassen-Invarianten (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Gegeben ist die Definition dreier Klassen `BBox`, `Cirlce` und `Triangle`. Die Klassen sind sog. `aggregate`-Klassen und weisen u.A. folgende Eigenschaften auf:\n",
|
||||
"\n",
|
||||
"- Ausschließlich öffentliche Member-Variablen\n",
|
||||
"- Keine benutzerdefinierten Konstruktoren\n",
|
||||
"- Parameterlose Konstruktion möglich, z.B. `Aggregate aggregate = {};`\n",
|
||||
"- Listen-Initialisierung ist möglich, z.B. `Aggregate aggregate = { value1, valu2 };`\n",
|
||||
"- Struktuierte Zuweisung ist möglich, z.B. `const auto& [m1, m2] = aggregate;`\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie die folgenden Member-Funktionen:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"namespace task2 {\n",
|
||||
"\n",
|
||||
"using Vec2d = std::array<double, 2>;\n",
|
||||
"\n",
|
||||
"/// @brief Axis-aligned bounding box\n",
|
||||
"struct BBox {\n",
|
||||
" Vec2d min; ///< coord of bottom left corner\n",
|
||||
" Vec2d max; ///< coord of top right corner\n",
|
||||
" BBox scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" BBox translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/// @brief Circle\n",
|
||||
"struct Circle {\n",
|
||||
" Vec2d c; ///< coordinate of the center of the circle\n",
|
||||
" double r; ///< radius of the circle\n",
|
||||
" BBox bbox() const; // todo\n",
|
||||
" Circle scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" Circle rotate(const Vec2d& org, double angle) const; // todo\n",
|
||||
" Circle translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"\n",
|
||||
"/// @brief Triangle\n",
|
||||
"struct Triangle {\n",
|
||||
" std::array<Vec2d, 3> abc; ///< three corner points of the triangle\n",
|
||||
" BBox bbox() const; // todo\n",
|
||||
" Triangle scale(const Vec2d& org, double s) const; // todo\n",
|
||||
" Triangle rotate(const Vec2d& org, double angle) const;// todo\n",
|
||||
" Triangle translate(const Vec2d& offset) const; // todo\n",
|
||||
" bool check_invariants() const; // todo\n",
|
||||
"};\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklarationen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.hpp`](task2.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.cpp`](task2.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.cpp`](task2.test.cpp)\n",
|
||||
"- In [`task2.misc.hpp`](task2.misc.hpp)/[`task2.misc.cpp`](task2.misc.cpp) sind Hilfsfunktionen zum Ausgeben und Vergleichen der drei Klassen gegeben (diese werden bei den Tests verwendet, stehen Ihnen aber auch für Ihre Implementierung zur Verfügung).\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Nutzung von bereitgestellter Funktionalität sowie der Implementierung aus Aufgabe 2 zum Erstellen einer eigenen `.svg`-Grafik (1 Punkt)\n",
|
||||
"\n",
|
||||
"Sie sollten die Funktionalität, die Sie in Aufgabe 2 implementiert haben (Skalieren/Verschieben/Rotieren) nun selbst nutzen um eine `.svg`-Grafik zu erstellen.\n",
|
||||
"\n",
|
||||
"Nutzen Sie die bereitgestellte Funktion `task3::render_wrapper` um die `.svg`-Grafik zu generieren: Sie können die Typen aus Aufgabe 2 (`BBox/Circle/Triangle`) direkt übergeben:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"// std::vector<task2::BBox> boxes = [ ... ]\n",
|
||||
"// std::vector<task2::Circle> circles = [ ... ]\n",
|
||||
"// std::vector<task2::Triangle> triangles = [ ... ]\n",
|
||||
"task3::render_wrapper(\"myimage.svg\", boxes, triangles, triangles);\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Es gibt keine Vorgaben, lediglich, dass die erstellte Grafik mindestens 20 Elemente (Boxen/Kreise/Dreiecke) enthalten muss. \n",
|
||||
"\n",
|
||||
"Hier ein Beispiel wie so etwas aussehen kann \n",
|
||||
"\n",
|
||||
"- horizontal verschobene und skalierte \"Häuser\" mit \"Himmel\" aus zufällig angeordneten Kreisen:\n",
|
||||
"\n",
|
||||
"\t\n",
|
||||
"\n",
|
||||
"- horizontal verschobene \"Lokomotiven\"\n",
|
||||
"\n",
|
||||
"\t"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Implementieren Sie folgende Funktion:\n",
|
||||
"\n",
|
||||
"```cpp\n",
|
||||
"\n",
|
||||
"namespace task3 {\n",
|
||||
"\n",
|
||||
"int render_something(std::filesystem::path filepath); // todo\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.hpp`](task3.hpp)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task3.cpp`](task3.cpp)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.cpp`](task3.test.cpp)\n",
|
||||
"- In [`task3.misc.hpp`](task3.misc.hpp)/[`task3.misc.cpp`](task3.misc.cpp) finden Sie die oben erwähnte Hilfsfunktion `task3::render_wrapper`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `g++` und `python`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"g++ -g -std=c++20 task1.main.cpp -o build/task1\n",
|
||||
"g++ -g -Imodules -std=c++20 task2.cpp task2.misc.cpp task2.test.cpp -o build/task2\n",
|
||||
"g++ -g -Imodules -std=c++20 task2.cpp task2.misc.cpp task3.cpp task3.misc.cpp task3.test.cpp -o build/task3\n",
|
||||
"\n",
|
||||
"# run tests\n",
|
||||
"./build/task1\n",
|
||||
"./build/task2\n",
|
||||
"./build/task3\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):s\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"cmake --build build --config Debug # all\n",
|
||||
"# run tests\n",
|
||||
"ctest --test-dir build -C Debug -R task1 \n",
|
||||
"ctest --test-dir build -C Debug -R task2 \n",
|
||||
"ctest --test-dir build -C Debug -R task3 \n",
|
||||
"ctest --test-dir build -C Debug # all\n",
|
||||
"``` \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
1
exercise4/modules
Submodule
1
exercise4/modules
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit df348de23a73810279468501510b754bc622797f
|
||||
43
exercise4/task1.main.cpp
Normal file
43
exercise4/task1.main.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/// @file
|
||||
/// @brief Task1: "single-file" excutable C++ program
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
#include <array> // std::array
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
namespace task1 {
|
||||
|
||||
using Coord = std::array<double, 2>;
|
||||
|
||||
/// @todo Implement a function 'rotate_counter_clockwise' according to the description below:
|
||||
/// - the function receives a two-dimensional coordinate in form of a 'std::array<double, 2>'
|
||||
/// - the function receives a rotation angle (in radians) in form of a 'double'
|
||||
/// - the function rotates the coordinate counter clockwise around the origin
|
||||
/// - the function returns the rotated coordinate as a std::array<double, 2>
|
||||
|
||||
std::array<double, 2> rotate_counter_clockwise(const Coord& coord, double angle) {
|
||||
std::array<double, 2> rotated_coord = {0, 0};
|
||||
rotated_coord[0] = coord[0] * cos(angle) - coord[1] * sin(angle);
|
||||
rotated_coord[1] = coord[0] * sin(angle) + coord[1] * cos(angle);
|
||||
return rotated_coord;
|
||||
}
|
||||
|
||||
} // namespace task1
|
||||
|
||||
/// @todo Implement a main function conducting the following tasks in this order:
|
||||
/// - Create two coordinates (local variables):
|
||||
/// - std::array<double, 2> coord1 = {112,211};
|
||||
/// - std::array<double, 2> coord2 = {-42,23};
|
||||
/// - Use your 'rotate_counter_clockwise' function to rotate both coordinate by 180 degrees
|
||||
/// - Print the resulting rotated coordinates to the console
|
||||
/// - Hint: the expected coordinates after rotating 180 degrees are
|
||||
/// - std::array<double, 2> coord1_rotated = {-112,-211};
|
||||
/// - std::array<double, 2> coord2_rotated = {42,-23};
|
||||
int main() {
|
||||
std::array<double, 2> coord1 = {112, 211};
|
||||
std::cout << "Original coord1: " << coord1[0] << ", " << coord1[1] << std::endl;
|
||||
std::array<double, 2> coord1_rotated = task1::rotate_counter_clockwise(coord1, std::numbers::pi_v<double>);
|
||||
std::cout << "Rotated coord1: " << coord1_rotated[0] << ", " << coord1_rotated[1] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
171
exercise4/task2.cpp
Normal file
171
exercise4/task2.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/// @file
|
||||
/// @brief Task2: member function definitions/implementations
|
||||
|
||||
#include "task2.hpp" // task2::Vec2, task2::BBox, task2::Circle, task2::Triangle
|
||||
#include "task2.misc.hpp" // task2::operator<<, task2::isnan, task2::isclose
|
||||
|
||||
#include "modules/iue-num/numerics.hpp" // iue::num::isclose
|
||||
|
||||
/// @todo Include standard library headers as needed
|
||||
|
||||
|
||||
namespace task2 {
|
||||
|
||||
/// ==================================== Bounding Box =================================================
|
||||
/// @todo Implement the missing member functions for bounding box as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'BBox::scale'
|
||||
BBox BBox::scale(const Vec2d& org, double s) const {
|
||||
BBox scaled_box = *this;
|
||||
scaled_box.min[0] = org[0] + s * (min[0] - org[0]);
|
||||
scaled_box.min[1] = org[1] + s * (min[1] - org[1]);
|
||||
scaled_box.max[0] = org[0] + s * (max[0] - org[0]);
|
||||
scaled_box.max[1] = org[1] + s * (max[1] - org[1]);
|
||||
return scaled_box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'BBox::translate'
|
||||
BBox BBox::translate(const Vec2d& offset) const {
|
||||
BBox translated_box = *this;
|
||||
translated_box.min[0] += offset[0];
|
||||
translated_box.min[1] += offset[1];
|
||||
translated_box.max[0] += offset[0];
|
||||
translated_box.max[1] += offset[1];
|
||||
return translated_box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'BBox::check_invariants'
|
||||
bool BBox::check_invariants() const {
|
||||
if (std::isnan(min[0]) || std::isnan(min[1]) || std::isnan(max[0]) || std::isnan(max[1])) {
|
||||
return false;
|
||||
}
|
||||
if (min[0] > max[0] || min[1] > max[1]) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(min[0], max[0]) && iue::num::isclose(min[1], max[1])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// ==================================== Circle ================================================
|
||||
/// @todo Implement the missing member functions for Circle as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'Circle::bbox'
|
||||
BBox Circle::bbox() const {
|
||||
BBox box = {{c[0] - r, c[1] - r}, {c[0] + r, c[1] + r}};
|
||||
return box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::scale'
|
||||
Circle Circle::scale(const Vec2d& org, double s) const {
|
||||
Circle scaled_circle = *this;
|
||||
scaled_circle.c[0] = org[0] + s * (c[0] - org[0]);
|
||||
scaled_circle.c[1] = org[1] + s * (c[1] - org[1]);
|
||||
scaled_circle.r *= s;
|
||||
return scaled_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::rotate'
|
||||
Circle Circle::rotate(const Vec2d& org, double angle) const {
|
||||
Circle rotated_circle = *this;
|
||||
double x = c[0] - org[0];
|
||||
double y = c[1] - org[1];
|
||||
rotated_circle.c[0] = org[0] + x * cos(angle) - y * sin(angle);
|
||||
rotated_circle.c[1] = org[1] + x * sin(angle) + y * cos(angle);
|
||||
return rotated_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::translate'
|
||||
Circle Circle::translate(const Vec2d& offset) const {
|
||||
Circle translated_circle = *this;
|
||||
translated_circle.c[0] += offset[0];
|
||||
translated_circle.c[1] += offset[1];
|
||||
return translated_circle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Circle::check_invariants'
|
||||
bool Circle::check_invariants() const {
|
||||
if (std::isnan(c[0]) || std::isnan(c[1]) || std::isnan(r)) {
|
||||
return false;
|
||||
}
|
||||
if (r < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ==================================== Triangle ================================================
|
||||
/// @todo Implement the missing member functions for Triangle as declared and specified in task2.hpp
|
||||
|
||||
/// @todo implement member function 'Triangle::bbox'
|
||||
BBox Triangle::bbox() const {
|
||||
BBox box = {{abc[0][0], abc[0][1]}, {abc[0][0], abc[0][1]}};
|
||||
for (int i = 1; i < 3; i++) {
|
||||
if (abc[i][0] < box.min[0]) {
|
||||
box.min[0] = abc[i][0];
|
||||
}
|
||||
if (abc[i][0] > box.max[0]) {
|
||||
box.max[0] = abc[i][0];
|
||||
}
|
||||
if (abc[i][1] < box.min[1]) {
|
||||
box.min[1] = abc[i][1];
|
||||
}
|
||||
if (abc[i][1] > box.max[1]) {
|
||||
box.max[1] = abc[i][1];
|
||||
}
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::scale'
|
||||
Triangle Triangle::scale(const Vec2d& org, double s) const {
|
||||
Triangle scaled_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
scaled_triangle.abc[i][0] = org[0] + s * (abc[i][0] - org[0]);
|
||||
scaled_triangle.abc[i][1] = org[1] + s * (abc[i][1] - org[1]);
|
||||
}
|
||||
return scaled_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::rotate'
|
||||
Triangle Triangle::rotate(const Vec2d& org, double angle) const {
|
||||
Triangle rotated_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
double x = abc[i][0] - org[0];
|
||||
double y = abc[i][1] - org[1];
|
||||
rotated_triangle.abc[i][0] = org[0] + x * cos(angle) - y * sin(angle);
|
||||
rotated_triangle.abc[i][1] = org[1] + x * sin(angle) + y * cos(angle);
|
||||
}
|
||||
return rotated_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::translate'
|
||||
Triangle Triangle::translate(const Vec2d& offset) const {
|
||||
Triangle translated_triangle = *this;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
translated_triangle.abc[i][0] += offset[0];
|
||||
translated_triangle.abc[i][1] += offset[1];
|
||||
}
|
||||
return translated_triangle;
|
||||
}
|
||||
|
||||
/// @todo implement member function 'Triangle::bbox'
|
||||
bool Triangle::check_invariants() const {
|
||||
if (std::isnan(abc[0][0]) || std::isnan(abc[0][1]) || std::isnan(abc[1][0]) || std::isnan(abc[1][1]) || std::isnan(abc[2][0]) || std::isnan(abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[0][0], abc[1][0]) && iue::num::isclose(abc[0][1], abc[1][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[0][0], abc[2][0]) && iue::num::isclose(abc[0][1], abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
if (iue::num::isclose(abc[1][0], abc[2][0]) && iue::num::isclose(abc[1][1], abc[2][1])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace task2
|
||||
87
exercise4/task2.hpp
Normal file
87
exercise4/task2.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
/// @file
|
||||
/// @brief Task2: class definitions with member function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array> // std::array
|
||||
|
||||
namespace task2 {
|
||||
|
||||
using Vec2d = std::array<double, 2>;
|
||||
|
||||
/// @brief Axis-aligned bounding box
|
||||
struct BBox {
|
||||
|
||||
Vec2d min; ///< coord of bottom left corner
|
||||
Vec2d max; ///< coord of top right corner
|
||||
|
||||
/// @brief Scales the bounding box (relative to a reference coordinate)
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
BBox scale(const Vec2d& org, double s) const;
|
||||
/// @brief Translates the line
|
||||
/// @param offset Translation vector
|
||||
BBox translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// Invariants:
|
||||
/// - no coordinate is NAN
|
||||
/// - the individual coordinates of 'min' are less or equal the respective coordinates in 'max'
|
||||
/// - 'min' is not close to 'max' (use iue::num::isclose to check)
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
/// @brief Circle
|
||||
struct Circle {
|
||||
|
||||
Vec2d c; ///< coordinate of the center of the circle
|
||||
double r; ///< radius of the circle
|
||||
|
||||
/// @brief Generates the minimum axis-aligned bounding box containing this circle
|
||||
/// @return axis-aligned bounding box
|
||||
BBox bbox() const;
|
||||
/// @brief Scales the circle center (relative to a reference coordinate), and the radius with a scalar value
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
Circle scale(const Vec2d& org, double s) const;
|
||||
/// @brief Rotates the circle center (relative to a reference coordinate) counter clockwise
|
||||
/// @param org Reference coordinate
|
||||
/// @param angle Rotation angle (in radians)
|
||||
Circle rotate(const Vec2d& org, double angle) const;
|
||||
/// @brief Translates the circle center
|
||||
/// @param offset Translation vector
|
||||
Circle translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// @note Invariants: radius is non-negative and no coordinate is NAN
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
/// @brief Triangle
|
||||
struct Triangle {
|
||||
|
||||
std::array<Vec2d, 3> abc; ///< three corner points of the triangle
|
||||
|
||||
/// @brief Generates the minimum axis-aligned bounding box containing this triangle
|
||||
/// @return axis-aligned bounding box
|
||||
BBox bbox() const;
|
||||
/// @brief Scales the triangle (relative to a reference coordinate)
|
||||
/// @param org Reference coordinate
|
||||
/// @param s Scaling factor
|
||||
Triangle scale(const Vec2d& org, double s) const;
|
||||
/// @brief Rotates the triangle (relative to a reference coordinate) counter clockwise
|
||||
/// @param org Reference coordinate
|
||||
/// @param angle Rotation angle (in radians)
|
||||
Triangle rotate(const Vec2d& org, double angle) const;
|
||||
/// @brief Translates the line
|
||||
/// @param offset Translation vector
|
||||
Triangle translate(const Vec2d& offset) const;
|
||||
/// @brief Checks if all invariants are fullfilled
|
||||
/// @return false if any invariant is violated, true otherwise
|
||||
/// Invariants:
|
||||
/// - no coordinate is NAN
|
||||
/// - none of the corner points are close to each other (use iue::num::isclose to check)
|
||||
bool check_invariants() const;
|
||||
};
|
||||
|
||||
} // namespace task2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user