Commit 6e0cd8a5 authored by Ben Huber's avatar Ben Huber

make the new jekyll documentation the default

parent fdf94b53
......@@ -13,6 +13,7 @@
!*.mk
!Makefile
!.gitignore
!*.sh
......@@ -24,6 +25,7 @@
!*.dox
!*.css
!*.js
!*.yml
# ...even if they are in subdirectories
!*/
......@@ -31,6 +33,5 @@
# However we really want to ignore
lapacke/*
build/*
doc/latex/*
doc/html/*
config.mk
......@@ -6,6 +6,7 @@ help:
\t\tshared \t\t -- Build xerus as a shared library.\n \
\t\tstatic \t\t -- Build xerus as a static library.\n \
\t\tpython \t\t -- Build the xerus python wrappers.\n \
\t\tdoc \t\t -- Build the html documentation for the xerus library.\n \
\t\tinstall \t -- Install the shared library and header files (may require root).\n \
\t\ttest \t\t -- Build and run the xerus unit tests.\n \
\t\tclean \t\t -- Remove all object, library and executable files.\n"
......@@ -186,7 +187,6 @@ ifdef DESTDIR
endif
ifdef INSTALL_LIB_PATH
ifdef INSTALL_HEADER_PATH
install: shared
......@@ -223,11 +223,17 @@ fullTest: $(TUTORIALS) $(TEST_NAME)
./$(TEST_NAME) all
.FORCE:
doc: .FORCE
make -C doc doc
clean:
rm -fr build
-rm -f $(TEST_NAME)
-rm -f include/xerus.h.gch
-rm -r doc/html
benchmark: $(MINIMAL_DEPS) $(LOCAL_HEADERS) benchmark.cxx $(LIB_NAME_STATIC)
......
# ------------------------------------------------------------------------------------------------------
# Default rule should be the help message
# ------------------------------------------------------------------------------------------------------
help:
@printf "Possible make targets are:\n \
\t\thelp \t\t -- Print this help.\n \
\t\tdoc \t\t -- Build the html documentation for the xerus library.\n \
\t\tserve \t\t -- Build the html documentation for the xerus library and offer it via 'jekyll serve'.\n \
\t\tclean \t\t -- Remove all documentation files.\n"
doc:
-mkdir html
doxygen doxygen/Doxyfile
jekyll build --source jekyll/ --destination html/
clean:
-rm -r html
serve:
-mkdir html
doxygen doxygen/Doxyfile
jekyll serve --source jekyll/ --destination html/
# Building Xerus
## Obtaining Xerus
You can get the source-code of the `xerus` library via [git](https://git.hemio.de/xerus/xerus/tree/master) or as an [archiv](https://git.hemio.de/xerus/xerus/repository/archive.tar.gz?ref=master).
For example to clone the repository with the latest stable version under linux simply type
~~~
git clone https://git.hemio.de/xerus/xerus.git
~~~
## Dependencies and Configuration
`Xerus` depends on several well established libraries, usually pre-installed or available through the standard package managers. In particular `lapacke`, `CXSparse`, `binutils`
and their dependencies. Also note that at at least version 4.8 of the `GCC` is required, as this is the first version to offer support for all `C++11` functionality used in `xerus`.
Make sure that all these are installed on your system before proceeding.
E.g. to install all dependencies on a fedora system execute
~~~
dnf install gcc-c++ openblas-devel suitesparse-devel lapack-devel binutils-devel
~~~
After downloading the source it is necessary to set a number of options that are somewhat individual to your system and needs. All following build steps assume that these
options are set in the `config.mk` file. Reasonable default values can be found in the `config.mk.default` file.
In particular the optimization level is interesting and the paths or standard flags for the required libraries need to be set. This way the `xerus` library can be compiled with any
`blas` compatible library for the matrix operations. For more details see the description in the `config.mk.default`
~~~
cp config.mk.default config.mk
nano config.mk
~~~
## Making Sure Everything Works as Intended
The sources include a number of unit tests that ensure that everything works as intended. To perform them simply input
~~~
make test -j4
~~~
(where `-j4` allows make to use up to 4 threads for the compilation). If all options were set correctly in the `config.mk` it should compile a test executable and launch it.
The output of this executable should then list a number of passed tests and end with
~~~
|
| total summary 132 of 132 passed
-------------------------------------------------------------------------------
|
| Total time elapsed: 10848.406 ms
-------------------------------------------------------------------------------
~~~
Note in particular, that all tests were passed. Should this not be the case please file a bug report with as many details as you
can in our [issuetracker](https://git.hemio.de/xerus/xerus/issues) or write us an [email](mailto:contact@libxerus.org).
## Building the Library
If all tests were passed you can build the library simply by calling make
~~~
make all -j4
~~~
this creates the shared library object `libxerus.so` as well as the static library object `libxerus.a`.
If you want to install `xerus` on your system to the path given in `config.mk` simply call (as root if necessary)
~~~
make install
~~~
## Compiling your own Applications Using Xerus
If `xerus` is properly installed on your system, compiling your own applications using `xerus` is as simple as using any other library. Just include `-lxerus` in your linker call and make sure to use
`-std=c++11` or `-std=c++14` in all compilation units that include `xerus.h` and everything should work.
If you want to use the static version of `xerus` you also have to include all libraries `xerus` depends on in your linker call. In particular these are lapacke (`-llapacke`),
lapack (`-llapack`), blas (`-lblas` or `-lopenblas` or similar), suitesparse (`-lumfpack -lspqr`), binutils (`-lbfd`). On some old system one has to manually include the dependencys of binutils (`-liberty -lz -ldl`).
You can test this by trying to compile the tutorial file (in this example without the installed `xerus` library)
~~~
g++ -std=c++11 tutorials/fulltensor.cpp libxerus.a -llapacke -llapack -lcblas -lblas -lcxsparse -lbfd -liberty -lz -ldl
~~~
......@@ -51,7 +51,7 @@ PROJECT_BRIEF = "a general purpose tensor library"
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO = xerus.svg
PROJECT_LOGO = doxygen/xerus.svg
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
......@@ -437,7 +437,7 @@ EXTRACT_PACKAGE = YES
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
......@@ -562,7 +562,7 @@ SORT_MEMBER_DOCS = YES
# this will also influence the order of the classes in the class list.
# The default value is: NO.
SORT_BRIEF_DOCS = NO
SORT_BRIEF_DOCS = YES
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
......@@ -574,7 +574,7 @@ SORT_BRIEF_DOCS = NO
# detailed member documentation.
# The default value is: NO.
SORT_MEMBERS_CTORS_1ST = NO
SORT_MEMBERS_CTORS_1ST = YES
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
......@@ -591,7 +591,7 @@ SORT_GROUP_NAMES = NO
# list.
# The default value is: NO.
SORT_BY_SCOPE_NAME = NO
SORT_BY_SCOPE_NAME = YES
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
# type resolution of all parameters of a function it will reject a match between
......@@ -687,7 +687,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
LAYOUT_FILE = doxygen/DoxygenLayout.xml
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
......@@ -708,7 +708,7 @@ CITE_BIB_FILES =
# messages are off.
# The default value is: NO.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
......@@ -740,7 +740,7 @@ WARN_IF_DOC_ERROR = YES
# parameter documentation, but not about the absence of documentation.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
WARN_NO_PARAMDOC = YES
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
......@@ -768,8 +768,7 @@ WARN_LOGFILE =
# spaces.
# Note: If this tag is empty the current directory is searched.
INPUT = . \
../tutorials/ \
INPUT = doxygen/ \
../include/ \
../include/xerus/ \
../include/xerus/algorithms/ \
......@@ -815,7 +814,7 @@ RECURSIVE = NO
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = *.hxx
EXCLUDE = *.cxx
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
......@@ -848,14 +847,14 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH = ../tutorials/
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.
EXAMPLE_PATTERNS = *
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
......@@ -916,7 +915,7 @@ FILTER_SOURCE_PATTERNS =
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE = mainpage.md
USE_MDFILE_AS_MAINPAGE = doxygen/mainpage.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
......@@ -1045,7 +1044,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html
HTML_OUTPUT = html/doxygen
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
......@@ -1072,7 +1071,7 @@ HTML_FILE_EXTENSION = .html
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER = header.html
HTML_HEADER = doxygen/header.html
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
......@@ -1082,7 +1081,7 @@ HTML_HEADER = header.html
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER = footer.html
HTML_FOOTER = doxygen/footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
......@@ -1094,7 +1093,7 @@ HTML_FOOTER = footer.html
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET = stylesheet.css
HTML_STYLESHEET = doxygen/stylesheet.css
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
......@@ -1107,7 +1106,7 @@ HTML_STYLESHEET = stylesheet.css
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET = DoxygenLayout.xml
HTML_EXTRA_STYLESHEET = doxygen/DoxygenLayout.xml
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
......@@ -1580,7 +1579,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = YES
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
......
......@@ -2,7 +2,8 @@
<!-- Generated by doxygen 1.8.3 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="user" url="/" title="Mainpage"/>
<!-- <tab type="mainpage" visible="yes" title=""/> -->
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
......@@ -19,7 +20,8 @@
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
<tab type="user" url="/documentation.html" title="Documentation"/>
<tab type="user" url="/examples.html" title="Examples"/>
<tab type="user" url="https://git.hemio.de/xerus/xerus" title="Git"/>
<tab type="user" url="https://git.hemio.de/xerus/xerus/issues" title="Issue-Tracker"/>
</navindex>
......
# xerus - a general purpose tensor library {#mainpage}
## Doxygen Documentation
This is the (automatically generated) Doxygen documentation for the `xerus` library. It is the only complete documentation (ie.
mentioning all classes and functions with at least a one-line description) but far less accessible than the documents of the
[main documentation](/documentation.html) or even the [examples](/examples.html).
It is advisable to use a modern IDE when working with any c++ source code, but in particular when using the `xerus` library. In
which case all of the information of this documentation should also be available from within your IDE as mouse-over text or similar.
If your IDE does not provide this functionality consider switching to `kdevelop`, `clion` or a similarly advanced IDE.
# Indices and Equations
## Blockwise Construction of Tensors
......@@ -18,3 +18,4 @@ markdown: kramdown
# gems: ['TabsConverter']
# exclude: ['README.md', 'LICENSE']
keep_files: ['doxygen']
......@@ -27,7 +27,7 @@ In practice, these projections can be obtained by simply contracting all fixed c
fixed components are orthogonolized). The ALS algorithm will now simply iterate over the components of $x$ and solve these smaller subproblems.
There are a few things we should note before we start implementing this algorithm
* It is enough to restrict ourselves to the case of symmetric positive-semidefinite operators $A$. Any non-symmetric problem can be solved by setting $A'=A^TA$ and $b' = A^Tb$.
* It is enough to restrict ourselves to the case of symmetric positive-semidefinite operators $A$. Any non-symmetric problem can be solved by setting $A'=A^TA$ and $b' = A^Tb$. We can thus use the identity $$\operatorname{argmin}_x \|Ax - b\|^2 = \operatorname{argmin}_x \left<x,Ax\right>-2\left<x,b\right>$$
* We should always move our core of $x$ to the position currrently being optimized to make our lives easier (for several reasons...).
* Calculating the local operators $\hat A$ for components $i$ and $i+1$ is highly redundant. All components of $x$ up to the $i-1$'st have to be contracted with $A$ in both cases. Effectively this means, that we will keep stacks of $x^TAx$ contracted up to the current index ("left" of the current index) as well as contracted at all indices above the currrent one ("right" of it) and similarly for $x^T b$.
......
# xerus - a general purpose tensor library {#mainpage}
## Introduction
The `xerus` library is a general purpose library for numerical calculations with higher order tensors, Tensor-Train Decompositions / Matrix Product States and general Tensor Networks.
The focus of development was the simple usability and adaptibility to any setting that requires higher order tensors or decompositions thereof.
The key features include:
* Modern code and concepts incorporating many features of the new `C++11` standard.
* Calculation with tensors of arbitrary orders using an intuitive Einstein-like notation `A(i,j) = B(i,k,l) * C(k,j,l);`.
* Full implementation of the Tensor-Train decompositions (MPS) with all neccessary capabilities (including Algorithms like ALS, ADF and CG).
* Lazy evaluation of multiple tensor contractions featuring heuristics to find the most effective contraction order.
* Direct integration of the `blas` and `lapack`, as high performance linear algebra backends.
* Fast sparse tensor calculation by usage of the `suiteSparse` sparse matrix capabilities.
* Capabilites to handle arbitrary Tensor Networks.
## Version History
We released our first stable version 1.0 in May 2015 and are currently at version 2.2.1. It can be obtained via [git](https://git.hemio.de/xerus/xerus) or as an archived download via the same link.
The current development version is also available in the same git repository (branch 'development') and it might include more features than the latest stable release, but be adviced that these development versions are particularly bad documented and might change drastically from one day to the next.
## Getting Started
There are a number of tutorials to get you started using the `xerus` library.
* [Building xerus](@ref md_building_xerus) - instruction on how to build the library iteself and your first own program using it.
* [Quick-Start guide](_quick-_start-example.html) - a short introduction into the basic `xerus` functionality.
* [Tensor Class](@ref md_tensor) - an introduction into the most important functions relating to the `xerus::Tensor` class.
* [TT Tensors](_t_t-_tensors_01_07_m_p_s_08-example.html) - using the MPS or Tensor-Train decomposition.
* [Optimization](@ref md_optimization) - some hints how to achieve the fastest possible numerical code using `xerus`.
* [Debugging](@ref md_tut_debugging) - using `xerus`'s capabilities to debug your own application.
## Issues
Should you have any problems with the library do not hesitate to contact us at [contact[at]libxerus.org](mailto:contact[at]libxerus.org) or describe your problem in the [issuetracker](https://git.hemio.de/xerus/xerus/issues).
## Licence and Attribution
The `xerus` library is published under the AGPL v3.0. With proper attribution you are thus allowed to freely use and modify the source code but if you distribute your software including the `xerus`
library (or you provide a service based on this library) you have to provide the full source code under a compatible licence. For more information see the [AGPL](http://www.gnu.org/licenses/agpl-3.0.html).
If this library proved useful in your scientific research we would be grateful for any contributions to the source code and citations. As there is no related article yet, a corresponding bibtex
entry might look as follows
~~~
@Misc{xerus,
author = {Huber, Benjamin and Wolf, Sebastian},
title = {Xerus - A General Purpose Tensor Library},
howpublished = {\url{https://libxerus.org/}},
year = {2014--2017}
}
~~~
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
# Nomenclature
Tensor (Network) methods were developed independently in several different fields. As such there is a large variety of different
names for the same concepts and at times even several concepts for the same name, depending on the context.
To avoid confusion we want to explain the terms as they are used throughout this library. Unfortunately we are not aware of any
introductory publication using our exact notation and nomenclature, but everybody familiar with the notation from Numerical Analysis
will be familiar with most definitions. We saw it necessary to expand these terms though to have precise names for every aspect.
Tensor, degree, dimension, mode, index, multi-index, position, span, slate, entry, (element - unused??), contraction, shuffling,
TensorNetwork, Node, external link
TTTensor, TTOperator, rounding, core, cannonical form, component
# Optimizations
If you are like us, you want to get the fastest possible version of your numerical code to run as many samples as possible and
solve the largest systems possible. To this end there are a number of possible optimizations already provided for you by the
`xerus` library. The following list expands on the most relevant of them in roughly the order of effectiveness.
## Disabling Runtime Checks
The library contains many runtime checks for out-of-bounds access, other invalid inputs (like illegal contractions), consistency
and even to check the correct behaviour of internal structures. Depending on the complexity your code and the time spent inside
`xerus` (and not one of the libraries it uses) you can expect a large performance gain by disabling these checks in the `config.mk`
file during compilation of xerus.
It is not advisable to do this while developing, as it will be much more difficult to detect errors in your calls to `xerus`
functions, but once you have established, that your code works as expected you might want to try replacing the `libxerus.so` object
used by your project with one compiled with the `-D XERUS_DISABLE_RUNTIME_CHECKS` flag.
## Use c++ instead of Python
The interface between the languages python and c++ makes it necessary to perform operations for the sole purpose of compatibility
between the otherwise incompatible languages. Often this includes copies of vectors of integers (whenever dimensions are specified
or queried) and sometimes even deep copies of whole tensors (`.from_ndarray()` and `.to_ndarray()`). The only way to get rid of
this overhead is to write your appliation in c++ instead of python. Most instructions that `xerus` offers for python look very
similar in c++, so a transition might be simpler than you think. Simply check out the rest of the tutorials to compare the code
snippets.
## Compiling Xerus with High Optimizations
Per default the library already compiles with high optimization settings (corresponding basically to `-O3`) as there is rarely
any reason to use lower settings for numerical code. If you want to spend a significant amount of cpu hours in numerical code
using the `xerus` library though, it might be worthwile to go even further.
The most significant change in runtime speed gains due to compiler settings at this point will come from link-time optimizations
(for `c++`projects using `xerus`).
To make use of them you will need a sufficiently recent versions of the `g++` compiler and `ar` archiver. After compiling the
`libxerus.so` object with the `USE_LTO = TRUE` flag you can then enable `-flto` in your own compilation process. The optimizations
that will be used then extending more than a single compilation unit and might thus use significant system resources during
compilation.
If link-time optimization is not an option (or not sufficient) it is also possible to replace the high optimizations flag in your
`config.mk` file with the `DANGEROUS_OPTIMIZATION = TRUE` flag. This will enable non-IEEE-conform optimizations that should
typically only change floating point results in the least significant bit but might lead to undefined behaviour in case a `NaN`
or overflow is encountered during runtime. (It is rumored that there is an even higher optimization setting available for `xerus`
for those who know how to find it and want to get even the last 1% of speedup...)
## Avoiding Indexed Expressions
The comfort of being able to write Einstein-notation-like equations in the source code of the form `A(i,k) = B(i,j)*C(j,k);`
comes with the price of a certain overhead during runtime. It is in the low single-digit percent range for typical applications
but can become significant when very small tensors are being used and the time for the actual contraction thus becomes negligible.
In such cases it can be useful to replace such equations (especially ones that are as simple as above) with the explicit statement
of contractions and reshuffels. For above equation that would simply be
~~~.cpp
contract(A, B, false, C, false, 1);
~~~
i.e. read as: contract two tensors and store the result in A, left hand side B, not transposed, right hand side C, not transposed, contract a single mode.
If it is necessary to reshuffle a tensor to be able to contract it in such a way, e.g. `A(i,j,k) = B(i,k,j)`, this can be done
with the `reshuffle` function.
~~~.cpp
reshuffle(A, B, {0,2,1});
~~~
It is our opinion that code written with these functions instead of indexed espressions are often much harder to understand
and the speedup is typically small... but just in case you really want to, you now have the option to use them.
This diff is collapsed.
# Debugging
`xerus` comes with a number of functionalities to simplify debugging. The purpose of this page is to explain the most important ones.
## LOG
The library uses a macro of the form `XERUS_LOG(level, msg)` to print messages to `cout`. It allows to use arbitrary log levels without any need to declare them beforehand
and to use typical piping syntax for the messages.
~~~.cpp
XERUS_LOG(als_warning, "The ALS encountered a mishap " << variable_1 << " <= " << variable_2);
~~~
The following warning levels are predefined: `fatal`, `critical`, `error`, `warning`, `info`, `debug`. The default config file `config.mk.default` defines the preprocessor
variable `XERUS_LOG_INFO` which causes all but the `debug` level to be printed. Per default any other log-level is printed. This can be turned off by including
`XERUS_SET_LOGGING(level, xerus::err::NO_LOGGING)` inside a commonly included header.
The `fatal` loglevel is special in that it will not just print the message but also throw an exception including the message itself and a callstack in the `.what()` string.
With the additional option `LOGGING += -D XERUS_LOG_BUFFER` in the `config.mk` file, any not printed log message will be stored in a circular buffer and will be dumped to a file
in the `errors/` subfolder (if it exists) on any `error`, `critical` or `fatal` log message.
## REQUIRE
The `XERUS_REQUIRE(condition, additional_msg)` macro replaces assertions in the `xerus` library. It uses above `XERUS_LOG` functionality and can thus use piping style messages just as the `XERUS_LOG`
macro. It is equivalent to the following definition
~~~.cpp
XERUS_REQUIRE(condition, additional_msg) = if (!(condition)) { XERUS_LOG(fatal, additional_msg); }
~~~
There is a large number of such checks in the library. All of them can be turned off by defining `DEBUG += -D XERUS_DISABLE_RUNTIME_CHECKS` in the `config.mk` file.
## UNIT_TEST
Compiling with `make test` creates an executable that includes all functions defined within `xerus::UnitTest` objects.
~~~.cpp
static xerus::misc::UnitTest objectName("Group", "Name", [](){
// source code of the test
// likely includes (several) tests of the form TEST(condition);
TEST(true);
});
~~~
This will only include the
unit tests in the library but can easily be extended should you wish to use it for your own executable. The created executable can be launched manually to perform individual
tests (eg. `./XerusTest TTTensor:summation`) or reperform all of them (`./XerusTest all`).
With the additional `config.mk` option `DEBUG += -D XERUS_TEST_COVERAGE`, the executable will track which `XERUS_REQUIRE` and `XERUS_REQUIRE_TEST` macros were executed during the run to advice
about function that need additional testing.
## Callstacks and XERUS_THROW
Unless `XERUS_NO_FANCY_CALLSTACK = TRUE` was declared in the `config.mk` file, the function `xerus::misc::get_call_stack()` will return a formatted string of the full stack trace including function name,
source file and line numbers. This stack will in particular be included in the exceptions thrown by `XERUS_LOG(fatal, ...)` and `XERUS_REQUIRE(...)` macros to simplify the detection of errors.
The information of this callstack is only available if the application was compiled with the `-g` flag and the linking requires the `binutils` packages `-lbfd -lz -ldl -liberty`.
The exceptions used by `xerus` have the additional capability to accept piped information that will be included in the `.what()` string. To include a callstack it is thus possible to
simply write
~~~.cpp
XERUS_THROW(xerus::misc::generic_error() << "callstack:\n" << xerus::misc::get_call_stack());
~~~
The used macro will additionally include the source file and line as well as the function name in which the exception was thrown.
This diff is collapsed.
/** @example "Quick-Start"
This quick-start guide will introduce some basic functionality of the `xerus` library.
It demonstrates the general layout and is enough for very basic applications but it is recommended to also have a look
at the more detailed guides for all classes one wishes to use - or even have a look at the class documentation for details on all functions.
It is assumed that you have already obtained and compiled the library itself as well as know how to link against it.
If this is not the case, please refer to the [building xerus](@ref md_building_xerus) page.
In the following we will solve a FEM equation arising from the heat equation using a QTT decomposition and the ALS algorithm.
To start we create the stiffness matrix as a full (ie. not sparse or decomposed) tensor.
To define the entries we pass a lambda function to the constructor of the `FullTensor` object that will be
called for every entry with a vector of size_t integers defining the indices of the current entry.
As it is simpler to think of the stiffness matrix in its original form rather than the QTT form we will
set the dimensions to `{512,512}`, ie. create it as a 512x512 tensor.
\dontinclude quickStart.cpp
\skip Tensor
\until });
To account for the @f$ h^2 @f$ factor that we have ignored to far we simply multipy the operator by @f$ N^2 @f$.
\skipline *=
By reinterpreting the dimension and thus effectively treating the tensor as a @f$ 2^{18} @f$ instead of a @f$ 512^2 @f$ tensor,
the decomposition into a `TTTensor` will give us the stiffness matrix in a QTT format.
\skip reinterpret_dimensions
\until ttA
As the Laplace operator is representable exactly in a low-rank QTT format, the rank of this `ttA` should be low after this construction.
We can verify this by printing the ranks:
\skipline cout
For the right-hand-side we perform similar operations to obtain a QTT decomposed vector @f$ b_i = 1 \forall i @f$.
As the generating lambda function needs no index information, we create a `[]()->double` lambda function:
\skip Tensor
\until ttb
To have an initial vector for the ALS algorithm we create a random TTTensor of the desired rank
(3 in this case - note, that this is the exact rank of the solution). This requires the definition
of a random number generator and distribution that will be used for the creation of the tensor.
\skip rnd
\until ttx
With these three tensors (the operator `ttA`, the right-hand-side `ttb` and the initial guess `ttx`)
we can now perform the ALS algorithm to solve for `ttx` (note here, that the _SPD suffix chooses the variant of the ALS
that assumes that the given operators are symmetric positive definite)
\skipline xerus::ALS_SPD
To verify the calculation performed by the ALS we will need to perform some arithmetic operations.
As these require the definition of (relative) index orderings in the tensors, we define some indices
\skipline Index
and use these in calculations like `A(i,j)*x(j) - b(i)`. Note though, that our tensors are of a higher
degree due to the QTT decomposition and we thus need to specify the corresponding dimension of the
multiindices i,j, and k with eg. `i^9` to denote a multiindex of dimension 9.
\skip frob_norm
\until cout
To get the actual error of the ALS solution (rather than just the residual) we can calculate the exact solution
of the system using the FullTensors A, x and b and the / operator
\skip xerus::Tensor
\until /
In the comparison of this exact solution `x` and the ALS solution `ttx` the TTTensor will automatically be
cast to a FullTensor to allow the subtraction. Here we can use another index shorthand: `i&0` which denotes
a multiindex of large enough dimension to fullz index the respective tensor object.
\skipline cout
The expected output of this whole program now looks something like
~~~
ttA ranks: { 3, 3, 3, 3, 3, 3, 3, 3 }
residual: 4.93323e-11
error: 1.48729e-20
~~~
We could now also print the solution with `x.to_string()` or store in in a file to plot it with another program.
We could change our operator to define other FEM systems and many more things. As this is only a very short
introduction though, we will stop here and refer the interested reader to either the following more detailed guides or