init
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
@@ -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]
|
||||
@@ -0,0 +1,4 @@
|
||||
task1
|
||||
task2
|
||||
task3_cpp
|
||||
task3_py
|
||||
@@ -0,0 +1,4 @@
|
||||
task1.main.cpp
|
||||
task2.cpp
|
||||
task3.cpp
|
||||
task3.py
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
@@ -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)
|
||||
|
||||
@@ -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.**
|
||||
@@ -0,0 +1 @@
|
||||
-Imodules
|
||||
@@ -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
|
||||
}
|
||||
Submodule
+1
Submodule exercise3/modules added at b8ce24c87f
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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')
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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()
|
||||
Reference in New Issue
Block a user